VYPR
Moderate severityNVD Advisory· Published May 20, 2020· Updated Aug 4, 2024

CRLF injection in httplib2

CVE-2020-11078

Description

In httplib2 before version 0.18.0, an attacker controlling unescaped part of uri for httplib2.Http.request() could change request headers and body, send additional hidden requests to same server. This vulnerability impacts software that uses httplib2 with uri constructed by string concatenation, as opposed to proper urllib building with escaping. This has been fixed in 0.18.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
httplib2PyPI
< 0.18.00.18.0

Affected products

1

Patches

1
a1457cc31f32

IMPORTANT security vulnerability CWE-93 CRLF injection

https://github.com/httplib2/httplib2Sergey ShepelevMay 20, 2020via ghsa
4 files changed · +37 1
  • python2/httplib2/__init__.py+3 0 modified
    @@ -1985,6 +1985,9 @@ def request(
                     headers["user-agent"] = "Python-httplib2/%s (gzip)" % __version__
     
                 uri = iri2uri(uri)
    +            # Prevent CWE-75 space injection to manipulate request via part of uri.
    +            # Prevent CWE-93 CRLF injection to modify headers via part of uri.
    +            uri = uri.replace(" ", "%20").replace("\r", "%0D").replace("\n", "%0A")
     
                 (scheme, authority, request_uri, defrag_uri) = urlnorm(uri)
     
    
  • python3/httplib2/__init__.py+3 0 modified
    @@ -1790,6 +1790,9 @@ def request(
                     headers["user-agent"] = "Python-httplib2/%s (gzip)" % __version__
     
                 uri = iri2uri(uri)
    +            # Prevent CWE-75 space injection to manipulate request via part of uri.
    +            # Prevent CWE-93 CRLF injection to modify headers via part of uri.
    +            uri = uri.replace(" ", "%20").replace("\r", "%0D").replace("\n", "%0A")
     
                 (scheme, authority, request_uri, defrag_uri) = urlnorm(uri)
     
    
  • tests/__init__.py+1 1 modified
    @@ -75,7 +75,7 @@ def _fill(self, target=1, more=None, untilend=False):
                     chunk = b""
                 else:
                     chunk = self._sock.recv(8 << 10)
    -            # print('!!! recv', chunk)
    +            # print("!!! recv", chunk)
                 if not chunk:
                     self._end = True
                     if untilend:
    
  • tests/test_http.py+30 0 modified
    @@ -703,3 +703,33 @@ def test_custom_redirect_codes():
             response, content = http.request(uri, "GET")
             assert response.status == 301
             assert response.previous is None
    +
    +
    +def test_cwe93_inject_crlf():
    +    # https://cwe.mitre.org/data/definitions/93.html
    +    # GET /?q= HTTP/1.1      <- injected "HTTP/1.1" from attacker
    +    # injected: attack
    +    # ignore-http: HTTP/1.1  <- nominal "HTTP/1.1" from library
    +    # Host: localhost:57285
    +    http = httplib2.Http()
    +    with tests.server_reflect() as uri:
    +        danger_url = urllib.parse.urljoin(
    +            uri, "?q= HTTP/1.1\r\ninjected: attack\r\nignore-http:"
    +        )
    +        response, content = http.request(danger_url, "GET")
    +        assert response.status == 200
    +        req = tests.HttpRequest.from_bytes(content)
    +        assert req.headers.get("injected") is None
    +
    +
    +def test_inject_space():
    +    # Injecting space into request line is precursor to CWE-93 and possibly other injections
    +    http = httplib2.Http()
    +    with tests.server_reflect() as uri:
    +        # "\r\nignore-http:" suffix is nuance for current server implementation
    +        # please only pay attention to space after "?q="
    +        danger_url = urllib.parse.urljoin(uri, "?q= HTTP/1.1\r\nignore-http:")
    +        response, content = http.request(danger_url, "GET")
    +        assert response.status == 200
    +        req = tests.HttpRequest.from_bytes(content)
    +        assert req.uri == "/?q=%20HTTP/1.1%0D%0Aignore-http:"
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

22

News mentions

0

No linked articles in our index yet.