Skip to content

Commit a0283f0

Browse files
authored
security: fix URL truncation issue (#144)
1 parent 05e6b8e commit a0283f0

2 files changed

Lines changed: 16 additions & 0 deletions

File tree

httptools/parser/url_parser.pyx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ from . cimport url_cparser as uparser
1212

1313
__all__ = ('parse_url',)
1414

15+
DEF MAX_URL_LENGTH = (1 << 16) - 1
16+
1517
@cython.freelist(250)
1618
cdef class URL:
1719
cdef readonly bytes schema
@@ -63,6 +65,14 @@ def parse_url(url):
6365

6466
PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE)
6567
try:
68+
if py_buf.len > MAX_URL_LENGTH:
69+
# http_parser stores URL field offsets/lengths as uint16_t,
70+
# so URLs longer than this will cause silent truncation.
71+
# See https://github.com/MagicStack/httptools/issues/142
72+
raise HttpParserInvalidURLError(
73+
"url is too long: url length of {} bytes exceeds the "
74+
"maximum of {} bytes".format(py_buf.len, MAX_URL_LENGTH))
75+
6676
buf_data = <char*>py_buf.buf
6777
res = uparser.http_parser_parse_url(buf_data, py_buf.len, 0, parsed)
6878

tests/test_parser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,9 @@ def test_parser_url_9(self):
686686
def test_parser_url_10(self):
687687
with self.assertRaisesRegex(TypeError, 'a bytes-like object'):
688688
self.parse('dsf://aaa')
689+
690+
def test_parser_url_too_long(self):
691+
url = b'http://h/' + b'a' * 65535
692+
with self.assertRaisesRegex(httptools.HttpParserInvalidURLError,
693+
'url is too long'):
694+
self.parse(url)

0 commit comments

Comments
 (0)