GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [CVE-2024-11168] urlparse incorrectly retrieves IPv4 and regular name hosts from inside of brackets · Issue #103848 · python/cpython

[CVE-2024-11168] urlparse incorrectly retrieves IPv4 and regular name hosts from inside of brackets #103848

New issue
Copy link
New issue
Copy link
Closed
Closed
[CVE-2024-11168] urlparse incorrectly retrieves IPv4 and regular name hosts from inside of brackets#103848
Copy link
Assignees
gpshead
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@JohnJamesUtley
JohnJamesUtley
opened on Apr 25, 2023
Issue body actions

Background

RFC 3986 defines a host as follows

host = IP-literal / IPv4address / reg-name

Where

IP-literal = "[" ( IPv6address / IPvFuture  ) "]"
reg-name = *( unreserved / pct-encoded / sub-delims )
IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

WhatWG says that "A valid host string must be a valid domain string, a valid IPv4-address string, or: U+005B ([), followed by a valid IPv6-address string, followed by U+005D (])."

The Bug

This is code from Lib/urllib/parse.py:196-208 used for retrieving the hostname from the netloc

    @property
    def _hostinfo(self):
        netloc = self.netloc
        _, _, hostinfo = netloc.rpartition('@')
        _, have_open_br, bracketed = hostinfo.partition('[')
        if have_open_br:
            hostname, _, port = bracketed.partition(']')
            _, _, port = port.partition(':')
        else:
            hostname, _, port = hostinfo.partition(':')
        if not port:
            port = None
        return hostname, port

It will incorrectly retrieve IPv4 addresses and regular name hosts from inside brackets. This is in violation of both specifications.

Minimally reproducible example:

from urllib.parse import urlsplit

parsedURL = urlsplit('scheme://user@[regname]/Path')
print(parsedURL.hostname) # Prints 'regname'

Your environment

  • CPython versions tested on:
    • 3.12a7 (23cf1e2)
    • 3.10.10
  • Operating system and architecture:
    • Arch Linux x86_64

Linked PRs

  • gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format #103849
  • [3.11] gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (GH-103849) #104349
  • [3.10] gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (#103849) #126975
  • [3.9] gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (#103849) #126976

Activity

Next
  1. JohnJamesUtley
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Apr 25, 2023
  2. arhadthedev
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Apr 26, 2023
  3. gpshead
    self-assigned this
    on May 9, 2023
  4. gpshead
    added a commit that references this issue on May 10, 2023

    gh-103848: Adds checks to ensure that bracketed hosts found by urlspl…

    29f348e
  5. miss-islington
    added a commit that references this issue on May 10, 2023

    pythongh-103848: Adds checks to ensure that bracketed hosts found by …

    2665fa4
  6. gpshead
    added 2 commits that reference this issue on May 10, 2023

    [3.11] pythongh-103848: Adds checks to ensure that bracketed hosts fo…

    4ad4ee3

    [3.11] gh-103848: Adds checks to ensure that bracketed hosts found by…

    b2171a2
  7. carljm
    added a commit that references this issue on May 10, 2023

    Merge branch 'main' into fixloadsuperspec

    5976df9
  8. mjpieters commented on Jun 6, 2023

    @mjpieters
    mjpieters
    on Jun 6, 2023
    Contributor
    More actions

    As implemented, the URL scheme://foobar.[::1]/ is considered correct, but results in the hostname value of ::1. The hostname portion of the netloc is invalid however, as it doesn't start with [. Shouldn't the parser at least validate that the [ bracket is the first character or directly following a @?

  9. MarcoGlauser commented on Jun 12, 2023

    @MarcoGlauser
    MarcoGlauser
    on Jun 12, 2023
    More actions

    This change caused an issue on our system. We have brackets in a password. Since 3.11.4, urlparse tries to parse an ip address if it finds brackets. The brackets don't even have to be in the correct order.

    Running this code:

    from urllib.parse import urlparse
    urlparse("https://user:some]password[@host.com")

    In 3.11.3 it works as expected:

    ParseResult(scheme='https', netloc='user:some]password[@host.com', path='', params='', query='', fragment='')
    

    In 3.11.4 it throws an exception:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python3.11/urllib/parse.py", line 395, in urlparse
        splitresult = urlsplit(url, scheme, allow_fragments)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/urllib/parse.py", line 500, in urlsplit
        _check_bracketed_host(bracketed_host)
      File "/usr/local/lib/python3.11/urllib/parse.py", line 446, in _check_bracketed_host
        ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/local/lib/python3.11/ipaddress.py", line 54, in ip_address
        raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
    ValueError: '@host.com' does not appear to be an IPv4 or IPv6 address
  10. mjpieters commented on Jun 12, 2023

    @mjpieters
    mjpieters
    on Jun 12, 2023
    Contributor
    More actions

    This change caused an issue on our system. We have brackets in a password. Since 3.11.4, urlparse tries to parse an ip address if it finds brackets. The brackets don't even have to be in the correct order.

    Running this code:

    from urllib.parse import urlparse
    urlparse("https://user:some]password[@host.com")

    In 3.11.3 it works as expected:

    ParseResult(scheme='https', netloc='user:some]password[@host.com', path='', params='', query='', fragment='')
    

    That this worked before was a bug. urlparse() was violating the various and miriad URL standards before; [ and ] are reserved characters with meaning in the netloc portion of a URL (the part between the scheme:// and /path) and must be URL encoded. See the WhatWG living URL standard percent-encoding section; for the userinfo part (username + password), you need to encode:

    • U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), U+005B ([) to U+005E (^), inclusive, and U+007C (|).
    • U+003F (?), U+0060 (`), U+007B ({), and U+007D (}) (path percent-encode set).
    • U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>) (query percent-encode set).
    • U+0000 NULL to U+001F INFORMATION SEPARATOR ONE, inclusive, and all codepoints past U+007E (~) (C0 control percent-encode set)

    So this works:

    >>> from urllib.parse import urlparse
    >>> urlparse("https://user:some%5Dpassword%[email protected]")
    ParseResult(scheme='https', netloc='user:some%5Dpassword%[email protected]', path='', params='', query='', fragment='')
    >>> _.password
    'some%5Dpassword%5B'
    

    The password is still URL encoded, use urllib.parse.unquote() for that.

    Further references:

    • Wikipedia: URL encoding
    • RFC 3986, section 2.2 Reserved Characters
    Reacted by Marco Glauser, Gregory P. Smith and RacerZ
  11. MarcoGlauser commented on Jun 12, 2023

    @MarcoGlauser
    MarcoGlauser
    on Jun 12, 2023
    More actions

    Thank you for the clarification! This makes a lot of sense :)

  12. dbnicholson
    added a commit that references this issue on Jun 15, 2023

    Handle urlparse ValueError on invalid IP addresses in python >= 3.11

    a516347
  13. Jc2k commented on Jun 28, 2023

    @Jc2k
    Jc2k
    on Jun 28, 2023
    More actions

    I'm also hitting "ValueError: 'xxxxx' does not appear to be an IPv4 or IPv6 address" on code that was working.

    In my case I have no control over the input data, it's background noise from the internet that i'm parsing and analyzing. Some of the crap in my dataset is very much not standards compliant. None the less, as it was working and now isn't i figured i should 👍 before i start vendoring old versions of the stdlib into my project 😆

  14. openstack-mirroring
    added a commit that references this issue on Aug 9, 2023

    tests: Use valid IPv6 address

    171580c
  15. 21 remaining items

  16. flokli
    added 5 commits that reference this issue on Jan 21, 2025

    test_url.py: handle 3.9 and 3.10 for http://[2a01:5cc0:1:2:3:4] testcase

    fe70df6

    test_url.py: handle 3.9 and 3.10 for http://[2a01:5cc0:1:2:3:4] testcase

    d39f792

    test_url.py: handle 3.9 and 3.10 for http://[2a01:5cc0:1:2:3:4] testcase

    c9f9862

    test_url.py: handle 3.9 and 3.10 for http://[2a01:5cc0:1:2:3:4] testcase

    44dcf91

    python3.pkgs.w3lib: fix build with python 3.9 and 3.10

    e7b3410
  17. nixpkgs-ci
    added a commit that references this issue on Jan 22, 2025

    python3.pkgs.w3lib: fix build with python 3.9 and 3.10

    61e1e47
  18. Beuc commented on Mar 7, 2025

    @Beuc
    Beuc
    on Mar 7, 2025
    More actions

    My backport of fix for Python 3.6 (which with minimal changes applies to 3.4 as well, and with a lot of changes, including injecting ipaddress from https://github.com/phihag/ipaddress into the Python standard library, into 2.7) is at openSUSE-Python@4f2496b

    Hi @mcepl. I'm currently evaluating how to fix this in older Debian dists for 2.7, and FYI it seems the version from OpenSUSE Leap 15 (150000.74.1) doesn't fully fix it:

    $ PYTHONPATH=/root/rpmbuild/BUILD/Python-2.7.18/Lib \
      python2 -c 'import urlparse; print(urlparse.urlparse("https://user:some]password[@host.com"))'
    ParseResult(scheme='https', netloc='user:some]password[@host.com', path='', params='', query='', fragment='')
    

    (expected: ValueError)
    It seems CVE-2024-11168-validation-IPv6-addrs.patch fixes the "http://" special case but not the general case (which handles "httpS://"). I didn't check the 3.6 patch closely but it seems it's the opposite situation there.

    After fixing the above I also get a couple test_urlparse errors, related to passing non-unicode data to the ipaddress backport. Casting to Unicode ipaddress.ip_address(unicode(hostname)) appears to tame the testsuite.

  19. mcepl commented on Mar 8, 2025

    @mcepl
    mcepl
    on Mar 8, 2025
    Contributor
    More actions

    (expected: ValueError) It seems CVE-2024-11168-validation-IPv6-addrs.patch fixes the "http://" special case but not the general case (which handles "httpS://"). I didn't check the 3.6 patch closely but it seems it's the opposite situation there.

    After fixing the above I also get a couple test_urlparse errors, related to passing non-unicode data to the ipaddress backport. Casting to Unicode ipaddress.ip_address(unicode(hostname)) appears to tame the testsuite.

    Do you have a corrected patch? I am all ears!

  20. Beuc commented on Mar 8, 2025

    @Beuc
    Beuc
    on Mar 8, 2025
    More actions

    Do you have a corrected patch? I am all ears!

    Now yes :)
    OpenSUSE patch with corrections: https://salsa.debian.org/lts-team/packages/python2.7/-/blob/08639c6a31c4726e2862d2908a8a805be9c186df/debian/patches/CVE-2024-11168-opensuse.patch
    Alternate approach, without embedding (and having to maintain) ipaddress: https://salsa.debian.org/lts-team/packages/python2.7/-/blob/c62e4e05f86c0e14ae6aa405382268d3c97137c6/debian/patches/CVE-2024-11168.patch

  21. mcepl commented on Mar 13, 2025

    @mcepl
    mcepl
    on Mar 13, 2025 via email
    Contributor
    More actions
    On Sat Mar 8, 2025 at 9:20 AM CET, Beuc wrote: Now yes :) OpenSUSE patch with corrections: https://salsa.debian.org/lts-team/packages/python2.7/-/blob/08639c6a31c4726e2862d2908a8a805be9c186df/debian/patches/CVE-2024-11168-opensuse.patch Alternate approach, without embedding (and having to maintain) ipaddress: https://salsa.debian.org/lts-team/packages/python2.7/-/blob/c62e4e05f86c0e14ae6aa405382268d3c97137c6/debian/patches/CVE-2024-11168.patch
    Thank you. In the end I went just with the modification of the original patch, I like how similar the patch is on all versions of the interpreter.
  22. gentoo-bot
    added a commit that references this issue on Apr 9, 2025

    [3.11] pythongh-103848: Adds checks to ensure that bracketed hosts fo…

    28bc8e7
  23. hrnciar
    added a commit that references this issue on Apr 23, 2025

    00444: Security fix for CVE-2024-11168

    38e5d6c
  24. hroncok
    added a commit that references this issue on Jul 4, 2025

    00444: Security fix for CVE-2024-11168

    e40bece
  25. frenzymadness
    added a commit that references this issue on Aug 12, 2025

    00444: Security fix for CVE-2024-11168

    48dea74
  26. hroncok
    added a commit that references this issue on Feb 3, 2026

    00444: Security fix for CVE-2024-11168

    0258af6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @gpshead
    gpshead

Labels

stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.