Projects
Mega:23.09
python-tornado
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
_service:tar_scm:python-tornado.spec
Changed
@@ -1,11 +1,11 @@ %global _empty_manifest_terminate_build 0 Name: python-tornado -Version: 6.3.2 +Version: 6.3.3 Release: 1 Summary: Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. License: ASL 2.0 URL: http://www.tornadoweb.org/ -Source0: https://files.pythonhosted.org/packages/30/f0/6e5d85d422a26fd696a1f2613ab8119495c1ebb8f49e29f428d15daf79cc/tornado-6.3.2.tar.gz +Source0: https://files.pythonhosted.org/packages/source/t/tornado/tornado-%{version}.tar.gz %description Tornado is an open source version of the scalable, non-blocking web server and tools. @@ -72,6 +72,9 @@ %{_docdir}/* %changelog +* Fri Oct 13 2023 wen-minjuan <mjwen@isoftstone.com> - 6.3.3-1 +- Upgrade version to 6.3.3-1 + * Thu Jul 13 2023 liuyongshuai <ysliuci@isoftstone.com> - 6.3.2-1 - Upgrade version to 6.3.2-1
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="url">git@gitee.com:src-openeuler/python-tornado.git</param> <param name="scm">git</param> - <param name="revision">openEuler-23.09</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:tornado-6.3.2.tar.gz/PKG-INFO -> _service:tar_scm:tornado-6.3.3.tar.gz/PKG-INFO
Changed
@@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tornado -Version: 6.3.2 +Version: 6.3.3 Summary: Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. Home-page: http://www.tornadoweb.org/ Author: Facebook
View file
_service:tar_scm:tornado-6.3.2.tar.gz/docs/releases.rst -> _service:tar_scm:tornado-6.3.3.tar.gz/docs/releases.rst
Changed
@@ -4,6 +4,7 @@ .. toctree:: :maxdepth: 2 + releases/v6.3.3 releases/v6.3.2 releases/v6.3.1 releases/v6.3.0
View file
_service:tar_scm:tornado-6.3.3.tar.gz/docs/releases/v6.3.3.rst
Added
@@ -0,0 +1,12 @@ +What's new in Tornado 6.3.3 +=========================== + +Aug 11, 2023 +------------ + +Security improvements +~~~~~~~~~~~~~~~~~~~~~ + +- The ``Content-Length`` header and ``chunked`` ``Transfer-Encoding`` sizes are now parsed + more strictly (according to the relevant RFCs) to avoid potential request-smuggling + vulnerabilities when deployed behind certain proxies.
View file
_service:tar_scm:tornado-6.3.2.tar.gz/tornado.egg-info/PKG-INFO -> _service:tar_scm:tornado-6.3.3.tar.gz/tornado.egg-info/PKG-INFO
Changed
@@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tornado -Version: 6.3.2 +Version: 6.3.3 Summary: Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. Home-page: http://www.tornadoweb.org/ Author: Facebook
View file
_service:tar_scm:tornado-6.3.2.tar.gz/tornado.egg-info/SOURCES.txt -> _service:tar_scm:tornado-6.3.3.tar.gz/tornado.egg-info/SOURCES.txt
Changed
@@ -147,6 +147,7 @@ docs/releases/v6.3.0.rst docs/releases/v6.3.1.rst docs/releases/v6.3.2.rst +docs/releases/v6.3.3.rst tornado/__init__.py tornado/_locale_data.py tornado/auth.py
View file
_service:tar_scm:tornado-6.3.2.tar.gz/tornado/__init__.py -> _service:tar_scm:tornado-6.3.3.tar.gz/tornado/__init__.py
Changed
@@ -22,8 +22,8 @@ # is zero for an official release, positive for a development branch, # or negative for a release candidate or beta (after the base version # number has been incremented) -version = "6.3.2" -version_info = (6, 3, 2, 0) +version = "6.3.3" +version_info = (6, 3, 3, 0) import importlib import typing
View file
_service:tar_scm:tornado-6.3.2.tar.gz/tornado/http1connection.py -> _service:tar_scm:tornado-6.3.3.tar.gz/tornado/http1connection.py
Changed
@@ -442,7 +442,7 @@ ): self._expected_content_remaining = 0 elif "Content-Length" in headers: - self._expected_content_remaining = int(headers"Content-Length") + self._expected_content_remaining = parse_int(headers"Content-Length") else: self._expected_content_remaining = None # TODO: headers are supposed to be of type str, but we still have some @@ -618,7 +618,7 @@ headers"Content-Length" = pieces0 try: - content_length = int(headers"Content-Length") # type: Optionalint + content_length: Optionalint = parse_int(headers"Content-Length") except ValueError: # Handles non-integer Content-Length value. raise httputil.HTTPInputError( @@ -668,7 +668,10 @@ total_size = 0 while True: chunk_len_str = await self.stream.read_until(b"\r\n", max_bytes=64) - chunk_len = int(chunk_len_str.strip(), 16) + try: + chunk_len = parse_hex_int(native_str(chunk_len_str:-2)) + except ValueError: + raise httputil.HTTPInputError("invalid chunk size") if chunk_len == 0: crlf = await self.stream.read_bytes(2) if crlf != b"\r\n": @@ -842,3 +845,21 @@ await asyncio.sleep(0) finally: delegate.on_close(self) + + +DIGITS = re.compile(r"0-9+") +HEXDIGITS = re.compile(r"0-9a-fA-F+") + + +def parse_int(s: str) -> int: + """Parse a non-negative integer from a string.""" + if DIGITS.fullmatch(s) is None: + raise ValueError("not an integer: %r" % s) + return int(s) + + +def parse_hex_int(s: str) -> int: + """Parse a non-negative hexadecimal integer from a string.""" + if HEXDIGITS.fullmatch(s) is None: + raise ValueError("not a hexadecimal integer: %r" % s) + return int(s, 16)
View file
_service:tar_scm:tornado-6.3.2.tar.gz/tornado/test/httpserver_test.py -> _service:tar_scm:tornado-6.3.3.tar.gz/tornado/test/httpserver_test.py
Changed
@@ -18,7 +18,7 @@ ) from tornado.iostream import IOStream from tornado.locks import Event -from tornado.log import gen_log +from tornado.log import gen_log, app_log from tornado.netutil import ssl_options_to_context from tornado.simple_httpclient import SimpleAsyncHTTPClient from tornado.testing import ( @@ -41,6 +41,7 @@ import ssl import sys import tempfile +import textwrap import unittest import urllib.parse from io import BytesIO @@ -118,7 +119,7 @@ def get_ssl_options(self): return dict( ssl_version=self.get_ssl_version(), - **AsyncHTTPSTestCase.default_ssl_options() + **AsyncHTTPSTestCase.default_ssl_options(), ) def get_ssl_version(self): @@ -558,23 +559,60 @@ ) self.assertEqual(json_decode(response), {"foo": "bar"}) - @gen_test - def test_invalid_content_length(self): - with ExpectLog( - gen_log, ".*Only integer Content-Length is allowed", level=logging.INFO - ): - self.stream.write( - b"""\ + def test_chunked_request_body_invalid_size(self): + # Only hex digits are allowed in chunk sizes. Python's int() function + # also accepts underscores, so make sure we reject them here. + self.stream.write( + b"""\ POST /echo HTTP/1.1 -Content-Length: foo +Transfer-Encoding: chunked -bar +1_a +1234567890abcdef1234567890 +0 """.replace( - b"\n", b"\r\n" - ) + b"\n", b"\r\n" + ) + ) + with ExpectLog(gen_log, ".*invalid chunk size", level=logging.INFO): + start_line, headers, response = self.io_loop.run_sync( + lambda: read_stream_body(self.stream) ) - yield self.stream.read_until_close() + self.assertEqual(400, start_line.code) + + @gen_test + def test_invalid_content_length(self): + # HTTP only allows decimal digits in content-length. Make sure we don't + # accept anything else, with special attention to things accepted by the + # python int() function (leading plus signs and internal underscores). + test_cases = + ("alphabetic", "foo"), + ("leading plus", "+10"), + ("internal underscore", "1_0"), + + for name, value in test_cases: + with self.subTest(name=name), closing(IOStream(socket.socket())) as stream: + with ExpectLog( + gen_log, + ".*Only integer Content-Length is allowed", + level=logging.INFO, + ): + yield stream.connect(("127.0.0.1", self.get_http_port())) + stream.write( + utf8( + textwrap.dedent( + f"""\ + POST /echo HTTP/1.1 + Content-Length: {value} + Connection: close + + 1234567890 + """ + ).replace("\n", "\r\n") + ) + ) + yield stream.read_until_close() class XHeaderTest(HandlerBaseTestCase): @@ -1123,6 +1161,46 @@ ) +class InvalidOutputContentLengthTest(AsyncHTTPTestCase): + class MessageDelegate(HTTPMessageDelegate): + def __init__(self, connection): + self.connection = connection + + def headers_received(self, start_line, headers): + content_lengths = { + "normal": "10", + "alphabetic": "foo", + "leading plus": "+10", + "underscore": "1_0", + } + self.connection.write_headers( + ResponseStartLine("HTTP/1.1", 200, "OK"), + HTTPHeaders({"Content-Length": content_lengthsheaders"x-test"}), + ) + self.connection.write(b"1234567890") + self.connection.finish() + + def get_app(self): + class App(HTTPServerConnectionDelegate): + def start_request(self, server_conn, request_conn): + return InvalidOutputContentLengthTest.MessageDelegate(request_conn) + + return App() + + def test_invalid_output_content_length(self): + with self.subTest("normal"): + response = self.fetch("/", method="GET", headers={"x-test": "normal"}) + response.rethrow() + self.assertEqual(response.body, b"1234567890") + for test in "alphabetic", "leading plus", "underscore": + with self.subTest(test): + # This log matching could be tighter but I think I'm already + # over-testing here. + with ExpectLog(app_log, "Uncaught exception"): + with self.assertRaises(HTTPError): + self.fetch("/", method="GET", headers={"x-test": test}) + + class MaxHeaderSizeTest(AsyncHTTPTestCase): def get_app(self): return Application(("/", HelloWorldRequestHandler))
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2