From 8859df3b77eabf99a9b40c5e595bccaae4539ae0 Mon Sep 17 00:00:00 2001 From: Tom Most Date: Sun, 13 Mar 2022 23:19:39 -0700 Subject: [PATCH] Test for malformed chunk size and extensions Upstream-Status: Backport [https://github.com/twisted/twisted/commit/f22d0d9c889822adb7eaf84b42a20ff5f7c4d421] CVE: CVE-2022-24801 Signed-off-by: Gyorgy Sarvari --- src/twisted/web/test/test_http.py | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/twisted/web/test/test_http.py b/src/twisted/web/test/test_http.py index 8a7adc0..e686aeb 100644 --- a/src/twisted/web/test/test_http.py +++ b/src/twisted/web/test/test_http.py @@ -1371,6 +1371,22 @@ class ChunkedTransferEncodingTests(unittest.TestCase): p.dataReceived(b"3; x-foo=bar\r\nabc\r\n") self.assertEqual(L, [b"abc"]) + def test_extensionsMalformed(self): + """ + L{_ChunkedTransferDecoder.dataReceived} raises + L{_MalformedChunkedDataError} when the chunk extension fields contain + invalid characters. + + This is a potential request smuggling vector: see GHSA-c2jg-hw38-jrqq. + """ + for b in [*range(0, 0x09), *range(0x10, 0x21), *range(0x74, 0x80)]: + data = b"3; " + bytes((b,)) + b"\r\nabc\r\n" + p = http._ChunkedTransferDecoder( + lambda b: None, # pragma: nocov + lambda b: None, # pragma: nocov + ) + self.assertRaises(http._MalformedChunkedDataError, p.dataReceived, data) + def test_oversizedChunkSizeLine(self): """ L{_ChunkedTransferDecoder.dataReceived} raises @@ -1426,6 +1442,22 @@ class ChunkedTransferEncodingTests(unittest.TestCase): http._MalformedChunkedDataError, p.dataReceived, b"-3\r\nabc\r\n" ) + def test_malformedChunkSizeHex(self): + """ + L{_ChunkedTransferDecoder.dataReceived} raises + L{_MalformedChunkedDataError} when the chunk size is prefixed with + "0x", as if it were a Python integer literal. + + This is a potential request smuggling vector: see GHSA-c2jg-hw38-jrqq. + """ + p = http._ChunkedTransferDecoder( + lambda b: None, # pragma: nocov + lambda b: None, # pragma: nocov + ) + self.assertRaises( + http._MalformedChunkedDataError, p.dataReceived, b"0x3\r\nabc\r\n" + ) + def test_malformedChunkEnd(self): r""" L{_ChunkedTransferDecoder.dataReceived} raises @@ -1538,6 +1570,8 @@ class ChunkingTests(unittest.TestCase, ResponseTestMixin): chunked = b"".join(http.toChunk(s)) self.assertEqual((s, b""), http.fromChunk(chunked)) self.assertRaises(ValueError, http.fromChunk, b"-5\r\nmalformed!\r\n") + self.assertRaises(ValueError, http.fromChunk, b"0xa\r\nmalformed!\r\n") + self.assertRaises(ValueError, http.fromChunk, b"0XA\r\nmalformed!\r\n") def testConcatenatedChunks(self): chunked = b"".join([b"".join(http.toChunk(t)) for t in self.strings])