Bug 1883632 (CVE-2020-26137)

Summary: CVE-2020-26137 python-urllib3: CRLF injection via HTTP request method
Product: [Other] Security Response Reporter: Mauro Matteo Cascella <mcascell>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: apevec, aurelien, bmontgom, cstratak, dbecker, eparis, hhorak, hvyas, infra-sig, jburrell, jeremy, jjoyce, jokerman, jorton, jschluet, lbalhar, lhh, lpeer, mburns, metherid, mhroncok, ncoghlan, nstielau, orion, puebele, pviktori, python-maint, python-sig, rhos-maint, sclewis, scorneli, slavek.kabrda, slinaber, sponnaga, steve.traylen, tflink, TicoTimo, torsava, yselkowi
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
See Also: https://issues.redhat.com/browse/CRW-1269
Whiteboard:
Fixed In Version: urllib3 1.25.9 Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in python-urllib3. The HTTPConnection.request() does not properly validate CRLF sequences in the HTTP request method, potentially allowing manipulation of the request by injecting additional HTTP headers. The highest threat from this vulnerability is to confidentiality and integrity.
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-10-20 20:21:17 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1883727, 1883799, 1883800, 1883830, 1883870, 1883871, 1883872, 1883873, 1883876, 1883888, 1883889, 1883890, 1883891, 1883895, 1883899, 1883912, 1883913, 1883914, 1883915, 1883920, 1883921, 1883922, 1885284, 1885340, 1887224    
Bug Blocks: 1877556    

Description Mauro Matteo Cascella 2020-09-29 18:21:58 UTC
A security issue was found in python-urllib3. HTTPConnection.request() does not properly validate CRLF sequences in the HTTP request method, potentially allowing to manipulate the request by injecting additional HTTP headers. Note that CVE-2020-26116 is strictly related to this bug, as the same flaw was reported in both urllib3 and built-in modules httplib/http.client.

References:
* https://bugs.python.org/issue39603

Upstream patch PR (merged upstream):
* https://github.com/urllib3/urllib3/pull/1800

Upstream commit:
* https://github.com/urllib3/urllib3/commit/1dd69c5c5982fae7c87a620d487c2ebf7a6b436b

Comment 6 Mauro Matteo Cascella 2020-09-30 12:43:47 UTC
Created python-pip tracking bugs for this issue:

Affects: epel-6 [bug 1883871]
Affects: fedora-all [bug 1883873]


Created python-pip-epel tracking bugs for this issue:

Affects: epel-7 [bug 1883872]


Created python3-urllib3 tracking bugs for this issue:

Affects: epel-all [bug 1883870]

Comment 7 Mauro Matteo Cascella 2020-09-30 12:51:39 UTC
Created python-urllib3 tracking bugs for this issue:

Affects: fedora-all [bug 1883876]

Comment 13 Petr Viktorin (pviktori) 2020-09-30 15:20:00 UTC
As for the pip bugs, do we know where in pip can an attacker control the HTTP method used? AFAIK, pip itself uses GET and POST but doesn't let you do arbitrary requests.

Comment 14 Mauro Matteo Cascella 2020-09-30 18:17:43 UTC
In reply to comment #13:
> As for the pip bugs, do we know where in pip can an attacker control the
> HTTP method used? AFAIK, pip itself uses GET and POST but doesn't let you do
> arbitrary requests.

Hi Petr, we only have a reproducer for urllib3 and httplib/http.client. I created those bugs to account for the fact that pip is using a vulnerable version of urllib3 (and ideally it should be fixed). I thought this might lead to some troubles, but honestly I don't know if/how this could be exploited in pip. If there's no way for an external attacker to control the HTTP method, we can surely consider closing those bugs as NOTABUG. Thanks.

Comment 16 Lumír Balhar 2020-10-02 06:14:21 UTC
I've done an investigation of this security issue. The vulnerable method is `putrequest` from `HTTPConnection` class from `http.client` module in Python standard library. This issue is already fixed upstream for all supported Python versions.

`HTTPConnection` class in urllib3 inherits from the mentioned `HTTPConnection` class from the standard library which means that fixing the vulnerability only in Python itself should be enough. But, as far as I understand, the fix is implemented also in urllib3 because:
* the library doesn't want to wait for the next Python release and
* it still maintains support for Python 2.7 where this vulnerability won't be fixed in Python itself (upstream).

Pip bundles its own versions of requests and urllib3 and uses only the high level API of requests. I haven't found any possible way how a pip user migh modify the HTTP method when sending a HTTP request. And even if I would be wrong, we are going to fix this vulnerability in Python interpreters so the chain pip > requests > urllib3 > http.client will be fixed all at once.

Therefore I think we can close all pip bugs as notabug.

Comment 17 Lumír Balhar 2020-10-02 06:55:04 UTC
To prove what I said in the previous comment, here is an example of how the fix in Python itself fixes also python-urllib3 package and urllib3 bundled in pip. I'm using the reproducer from the security team.

# python34-3.4.10-6.el7.x86_64 (vulnerable)

$ python3.4 poc.py
<no error>

<second terminal>$ nc -l -p 3333
GET / HTTP/1.1
X-INJECTED: HEADER
REMAINDER: / HTTP/1.1
Host: localhost:3333
Accept-Encoding: identity

The situation is the same when I use the bundled urllib3 in pip via `PYTHONPATH=/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/ python3.4 poc.py`

# python34-3.4.10-7.el7.x86_64 (fixed, update: https://bodhi.fedoraproject.org/updates/FEDORA-EPEL-2020-bd6a96cd24)

$ python3.4 poc.py 
Traceback (most recent call last):
  File "poc.py", line 12, in <module>
    info = pool_manager.request(method, url)
  File "/usr/lib/python3.4/site-packages/urllib3/request.py", line 80, in request
    method, url, fields=fields, headers=headers, **urlopen_kw
  File "/usr/lib/python3.4/site-packages/urllib3/request.py", line 171, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "/usr/lib/python3.4/site-packages/urllib3/poolmanager.py", line 330, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/usr/lib/python3.4/site-packages/urllib3/connectionpool.py", line 672, in urlopen
    chunked=chunked,
  File "/usr/lib/python3.4/site-packages/urllib3/connectionpool.py", line 387, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib64/python3.4/http/client.py", line 1154, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib64/python3.4/http/client.py", line 1189, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/lib64/python3.4/http/client.py", line 1011, in putrequest
    self._validate_method(method)
  File "/usr/lib64/python3.4/http/client.py", line 1107, in _validate_method
    % (method, match.group()))
ValueError: method can't contain control characters. 'GET / HTTP/1.1\r\nX-INJECTED: HEADER\r\nREMAINDER:' (found at least '\r')

$ PYTHONPATH=/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/ python3.4 poc.py 
Traceback (most recent call last):
  File "poc.py", line 12, in <module>
    info = pool_manager.request(method, url)
  File "/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/request.py", line 73, in request
    **urlopen_kw)
  File "/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/request.py", line 151, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/poolmanager.py", line 166, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
    chunked=chunked)
  File "/usr/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/connectionpool.py", line 362, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib64/python3.4/http/client.py", line 1154, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib64/python3.4/http/client.py", line 1189, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/lib64/python3.4/http/client.py", line 1011, in putrequest
    self._validate_method(method)
  File "/usr/lib64/python3.4/http/client.py", line 1107, in _validate_method
    % (method, match.group()))
ValueError: method can't contain control characters. 'GET / HTTP/1.1\r\nX-INJECTED: HEADER\r\nREMAINDER:' (found at least '\r')

Comment 21 Summer Long 2020-10-11 22:30:23 UTC
Created python-urllib3 tracking bugs for this issue:

Affects: openstack-rdo [bug 1887224]

Comment 24 errata-xmlrpc 2020-10-20 20:00:30 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.6 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7.7 EUS

Via RHSA-2020:4299 https://access.redhat.com/errata/RHSA-2020:4299

Comment 25 Product Security DevOps Team 2020-10-20 20:21:17 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2020-26137

Comment 26 Summer Long 2020-11-10 04:01:20 UTC
Statement:

* Red Hat OpenShift Container Platform (OCP) 4 delivers the python-urllib3 package which includes vulnerable version of urllib3 module, however from OCP 4.6 the python-urllib3 package is no longer shipped and will not be fixed.
* In Red Hat OpenStack Platform, because the flaw has a lower impact and the fix would require a substantial amount of development, no update will be provided at this time for the RHOSP python-urllib3 package.

Note: Versions of `python-pip` are marked as not affected because there is no way for a pip user to control the HTTP request method.

Comment 27 Yaakov Selkowitz 2021-01-06 22:56:43 UTC
(In reply to Summer Long from comment #26)
> * Red Hat OpenShift Container Platform (OCP) 4 delivers the python-urllib3
> package which includes vulnerable version of urllib3 module, however from
> OCP 4.6 the python-urllib3 package is no longer shipped and will not be
> fixed.

OpenShift ships several container images which pull in RHEL8's python[3]-urllib3: the ironic* and kuryr* containers in all 4.y versions, and ansible-operator and its dependants in 4.6+.

Comment 28 errata-xmlrpc 2021-01-20 04:37:00 UTC
This issue has been addressed in the following products:

  Red Hat OpenShift Container Platform 4.5

Via RHSA-2021:0034 https://access.redhat.com/errata/RHSA-2021:0034

Comment 29 errata-xmlrpc 2021-01-20 16:53:20 UTC
This issue has been addressed in the following products:

  Red Hat OpenShift Container Platform 3.11

Via RHSA-2021:0079 https://access.redhat.com/errata/RHSA-2021:0079

Comment 30 errata-xmlrpc 2021-05-18 13:49:42 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2021:1631 https://access.redhat.com/errata/RHSA-2021:1631

Comment 31 errata-xmlrpc 2021-05-18 14:50:29 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2021:1761 https://access.redhat.com/errata/RHSA-2021:1761

Comment 32 errata-xmlrpc 2022-06-28 09:47:03 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2022:5235 https://access.redhat.com/errata/RHSA-2022:5235