Skip to content

Commit

Permalink
Ensure request headers are terminated by CRLF and not just CR
Browse files Browse the repository at this point in the history
Closes #368.
  • Loading branch information
lpereira committed Jul 30, 2024
1 parent dce8c22 commit 13e0c39
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lib/lwan-request.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,10 @@ static ALWAYS_INLINE ssize_t find_headers(char **header_start,
next_chr = next_header + HEADER_TERMINATOR_LEN;
if (UNLIKELY(next_chr >= buffer_end))
return -1;

/* Avoid request smuggling. More info: https://github.com/lpereira/lwan/issues/368 */
if (UNLIKELY(next_header[1] != '\n'))
return -1;
}

out:
Expand Down
11 changes: 11 additions & 0 deletions src/scripts/testsuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,17 @@ def test_cache_mmaps_once_even_after_timeout(self):
requests.get('http://127.0.0.1:8080/100.html')
self.assertEqual(self.count_mmaps('/100.html'), 1)


class TestHeaderParsing(SocketTest):
def test_check_for_crlf(self):
# https://github.com/lpereira/lwan/issues/368
req = '''GET /hello HTTP/1.1\r\nHost: a\rXContent-Length: 31\r\n\r\nGET /evil HTTP/1.1\r\nHost: a\r\n\r\n'''

with self.connect() as sock:
sock.send(req)
response = sock.recv(4096)
self.assertTrue(response.startswith('HTTP/1.1 400 Bad request'))

class TestProxyProtocolRequests(SocketTest):
def test_proxy_version1(self):
proxy = "PROXY TCP4 192.168.242.221 192.168.242.242 56324 31337\r\n"
Expand Down

0 comments on commit 13e0c39

Please sign in to comment.