summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python
diff options
context:
space:
mode:
authorSoumya Sambu <soumya.sambu@windriver.com>2025-09-16 18:26:20 +0530
committerGyorgy Sarvari <skandigraun@gmail.com>2025-09-18 09:53:56 +0200
commit84206e79174136ba060e63388072d513df7b4274 (patch)
treea84979c9c569b88caef0ea237e41d74d20ee0f1d /meta-python/recipes-devtools/python
parent7ca4d7761b546524fc7777eac79a8e058701ebda (diff)
downloadmeta-openembedded-84206e79174136ba060e63388072d513df7b4274.tar.gz
python3-twisted: Fix CVE-2023-46137
Twisted is an event-based framework for internet applications. Prior to version 23.10.0rc1, when sending multiple HTTP requests in one TCP packet, twisted.web will process the requests asynchronously without guaranteeing the response order. If one of the endpoints is controlled by an attacker, the attacker can delay the response on purpose to manipulate the response of the second request when a victim launched two requests using HTTP pipeline. Version 23.10.0rc1 contains a patch for this issue. References: https://nvd.nist.gov/vuln/detail/CVE-2023-46137 https://security-tracker.debian.org/tracker/CVE-2023-46137 Upstream patch: https://github.com/twisted/twisted/commit/1e6e9d23cac59689760558dcb6634285e694b04c Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
Diffstat (limited to 'meta-python/recipes-devtools/python')
-rw-r--r--meta-python/recipes-devtools/python/python3-twisted/CVE-2023-46137.patch196
-rw-r--r--meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb3
2 files changed, 198 insertions, 1 deletions
diff --git a/meta-python/recipes-devtools/python/python3-twisted/CVE-2023-46137.patch b/meta-python/recipes-devtools/python/python3-twisted/CVE-2023-46137.patch
new file mode 100644
index 0000000000..d504448885
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-twisted/CVE-2023-46137.patch
@@ -0,0 +1,196 @@
1From 1e6e9d23cac59689760558dcb6634285e694b04c Mon Sep 17 00:00:00 2001
2From: Glyph <glyph@twistedmatrix.com>
3Date: Tue Sep 12 11:32:55 2023 -0700
4Subject: [PATCH] 11976 stop processing pipelined HTTP/1.1 requests that are
5 received together (#11979)
6
7CVE: CVE-2023-46137
8
9Upstream-Status: Backport [https://github.com/twisted/twisted/commit/1e6e9d23cac59689760558dcb6634285e694b04c]
10
11Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
12---
13 src/twisted/web/http.py | 32 +++++++--
14 src/twisted/web/newsfragments/11976.bugfix | 7 ++
15 src/twisted/web/test/test_web.py | 81 +++++++++++++++++++++-
16 3 files changed, 114 insertions(+), 6 deletions(-)
17 create mode 100644 src/twisted/web/newsfragments/11976.bugfix
18
19diff --git a/src/twisted/web/http.py b/src/twisted/web/http.py
20index 96a1335..b99480f 100644
21--- a/src/twisted/web/http.py
22+++ b/src/twisted/web/http.py
23@@ -2366,14 +2366,38 @@ class HTTPChannel(basic.LineReceiver, policies.TimeoutMixin):
24
25 self._handlingRequest = True
26
27+ # We go into raw mode here even though we will be receiving lines next
28+ # in the protocol; however, this data will be buffered and then passed
29+ # back to line mode in the setLineMode call in requestDone.
30+ self.setRawMode()
31+
32 req = self.requests[-1]
33 req.requestReceived(command, path, version)
34
35- def dataReceived(self, data):
36+ def rawDataReceived(self, data: bytes) -> None:
37 """
38- Data was received from the network. Process it.
39+ This is called when this HTTP/1.1 parser is in raw mode rather than
40+ line mode.
41+
42+ It may be in raw mode for one of two reasons:
43+
44+ 1. All the headers of a request have been received and this
45+ L{HTTPChannel} is currently receiving its body.
46+
47+ 2. The full content of a request has been received and is currently
48+ being processed asynchronously, and this L{HTTPChannel} is
49+ buffering the data of all subsequent requests to be parsed
50+ later.
51+
52+ In the second state, the data will be played back later.
53+
54+ @note: This isn't really a public API, and should be invoked only by
55+ L{LineReceiver}'s line parsing logic. If you wish to drive an
56+ L{HTTPChannel} from a custom data source, call C{dataReceived} on
57+ it directly.
58+
59+ @see: L{LineReceive.rawDataReceived}
60 """
61- # If we're currently handling a request, buffer this data.
62 if self._handlingRequest:
63 self._dataBuffer.append(data)
64 if (
65@@ -2385,9 +2409,7 @@ class HTTPChannel(basic.LineReceiver, policies.TimeoutMixin):
66 # ready. See docstring for _optimisticEagerReadSize above.
67 self._networkProducer.pauseProducing()
68 return
69- return basic.LineReceiver.dataReceived(self, data)
70
71- def rawDataReceived(self, data):
72 self.resetTimeout()
73
74 try:
75diff --git a/src/twisted/web/newsfragments/11976.bugfix b/src/twisted/web/newsfragments/11976.bugfix
76new file mode 100644
77index 0000000..8ac292b
78--- /dev/null
79+++ b/src/twisted/web/newsfragments/11976.bugfix
80@@ -0,0 +1,7 @@
81+In Twisted 16.3.0, we changed twisted.web to stop dispatching HTTP/1.1
82+pipelined requests to application code. There was a bug in this change which
83+still allowed clients which could send multiple full HTTP requests in a single
84+TCP segment to trigger asynchronous processing of later requests, which could
85+lead to out-of-order responses. This has now been corrected and twisted.web
86+should never process a pipelined request over HTTP/1.1 until the previous
87+request has fully completed.
88diff --git a/src/twisted/web/test/test_web.py b/src/twisted/web/test/test_web.py
89index 3eb35a9..b2b2ad7 100644
90--- a/src/twisted/web/test/test_web.py
91+++ b/src/twisted/web/test/test_web.py
92@@ -8,6 +8,7 @@ Tests for various parts of L{twisted.web}.
93 import os
94 import zlib
95 from io import BytesIO
96+from typing import List
97
98 from zope.interface import implementer
99 from zope.interface.verify import verifyObject
100@@ -17,10 +18,13 @@ from twisted.internet.address import IPv4Address, IPv6Address
101 from twisted.internet.task import Clock
102 from twisted.logger import LogLevel, globalLogPublisher
103 from twisted.python import failure, reflect
104+from twisted.python.compat import iterbytes
105 from twisted.python.filepath import FilePath
106-from twisted.test.proto_helpers import EventLoggingObserver
107+from twisted.test.proto_helpers import EventLoggingObserver, StringTransport
108 from twisted.trial import unittest
109 from twisted.web import error, http, iweb, resource, server
110+from twisted.web.resource import Resource
111+from twisted.web.server import NOT_DONE_YET, Request, Site
112 from twisted.web.static import Data
113 from twisted.web.test.requesthelper import DummyChannel, DummyRequest
114 from ._util import assertIsFilesystemTemporary
115@@ -1849,3 +1853,78 @@ class ExplicitHTTPFactoryReactor(unittest.TestCase):
116
117 factory = http.HTTPFactory()
118 self.assertIs(factory.reactor, reactor)
119+
120+
121+class QueueResource(Resource):
122+ """
123+ Add all requests to an internal queue,
124+ without responding to the requests.
125+ You can access the requests from the queue and handle their response.
126+ """
127+
128+ isLeaf = True
129+
130+ def __init__(self) -> None:
131+ super().__init__()
132+ self.dispatchedRequests: List[Request] = []
133+
134+ def render_GET(self, request: Request) -> int:
135+ self.dispatchedRequests.append(request)
136+ return NOT_DONE_YET
137+
138+
139+class TestRFC9112Section932(unittest.TestCase):
140+ """
141+ Verify that HTTP/1.1 request ordering is preserved.
142+ """
143+
144+ def test_multipleRequestsInOneSegment(self) -> None:
145+ """
146+ Twisted MUST NOT respond to a second HTTP/1.1 request while the first
147+ is still pending.
148+ """
149+ qr = QueueResource()
150+ site = Site(qr)
151+ proto = site.buildProtocol(None)
152+ serverTransport = StringTransport()
153+ proto.makeConnection(serverTransport)
154+ proto.dataReceived(
155+ b"GET /first HTTP/1.1\r\nHost: a\r\n\r\n"
156+ b"GET /second HTTP/1.1\r\nHost: a\r\n\r\n"
157+ )
158+ # The TCP data contains 2 requests,
159+ # but only 1 request was dispatched,
160+ # as the first request was not yet finalized.
161+ self.assertEqual(len(qr.dispatchedRequests), 1)
162+ # The first request is finalized and the
163+ # second request is dispatched right away.
164+ qr.dispatchedRequests[0].finish()
165+ self.assertEqual(len(qr.dispatchedRequests), 2)
166+
167+ def test_multipleRequestsInDifferentSegments(self) -> None:
168+ """
169+ Twisted MUST NOT respond to a second HTTP/1.1 request while the first
170+ is still pending, even if the second request is received in a separate
171+ TCP package.
172+ """
173+ qr = QueueResource()
174+ site = Site(qr)
175+ proto = site.buildProtocol(None)
176+ serverTransport = StringTransport()
177+ proto.makeConnection(serverTransport)
178+ raw_data = (
179+ b"GET /first HTTP/1.1\r\nHost: a\r\n\r\n"
180+ b"GET /second HTTP/1.1\r\nHost: a\r\n\r\n"
181+ )
182+ # Just go byte by byte for the extreme case in which each byte is
183+ # received in a separate TCP package.
184+ for chunk in iterbytes(raw_data):
185+ proto.dataReceived(chunk)
186+ # The TCP data contains 2 requests,
187+ # but only 1 request was dispatched,
188+ # as the first request was not yet finalized.
189+ self.assertEqual(len(qr.dispatchedRequests), 1)
190+ # The first request is finalized and the
191+ # second request is dispatched right away.
192+ qr.dispatchedRequests[0].finish()
193+ self.assertEqual(len(qr.dispatchedRequests), 2)
194--
1952.40.0
196
diff --git a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
index ef602890ea..5b23ceeb91 100644
--- a/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
+++ b/meta-python/recipes-devtools/python/python3-twisted_22.2.0.bb
@@ -13,7 +13,8 @@ PYPI_PACKAGE = "Twisted"
13 13
14SRC_URI += "file://CVE-2024-41671-0001.patch \ 14SRC_URI += "file://CVE-2024-41671-0001.patch \
15 file://CVE-2024-41671-0002.patch \ 15 file://CVE-2024-41671-0002.patch \
16 file://CVE-2024-41810.patch" 16 file://CVE-2024-41810.patch \
17 file://CVE-2023-46137.patch"
17 18
18inherit pypi python_setuptools_build_meta 19inherit pypi python_setuptools_build_meta
19 20