You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CVE-2019-18348: CRLF injection via the host part of the url passed to urlopen() #82757
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee='https://github.com/benjaminp'closed_at=<Date2020-03-19.01:35:47.815>created_at=<Date2019-10-24.07:51:18.864>labels= ['type-security', 'library', 'release-blocker']
title='CVE-2019-18348: CRLF injection via the host part of the url passed to urlopen()'updated_at=<Date2022-02-28.20:23:55.129>user='https://github.com/ret2libc'
================
The commit b7378d7 is incomplete: it doesn't seem to check for control characters in the "host" part of the URL, only in the "path" part of the URL. Example:
---
try:
from urllib import request as urllib_request
except ImportError:
import urllib2 as urllib_request
import socket
def bug(*args):
raise Exception(args)
# urlopen() must not call create_connection()
socket.create_connection = bug
urllib_request.urlopen('http://127.0.0.1\\r\\n\\x20hihi\\r\\n :11211')
---
So urllib2/urllib.request actually does a real network connection (DNS query), whereas it should reject control characters in the "host" part of the URL.
A second problem comes into the game. Some C libraries like glibc strip the end of the hostname (strip at the first newline character) and so HTTP Header injection is still possible is this case: https://bugzilla.redhat.com/show_bug.cgi?id=1673465
According to the RFC 3986, the "host" grammar doesn't allow any control character, it looks like:
changed the title [-]CVE-2019-18348 CRLF injection via the host part of the url passed to urlopen()[/-][+]CVE-2019-18348: CRLF injection via the host part of the url passed to urlopen()[/+]on Oct 24, 2019
Can't see the specifics of that "restricted" redhat bug, but this was interesting bug and I wanted to ask if perhaps the domain in such cases should be IDN / punycoded ://xn--n28h.ws/ for example is ://💩.la
ret2libc commented on Nov 25, 2019
ret2libcmannequin
MannequinAuthor
More actions
The glibc issue mentioned in the first comment is CVE-2016-10739 .
mcepl commented on Feb 20, 2020
mceplmannequin
Mannequin
More actions
Just to say this is reproducible only on rather old enterprise Linux distributions, where CVE-2016-10739 bug in glibc has not been fixed. I believe it means RHEL-6, SUSE SLE-10, 11, 12 (not sure whether it applies to some old Debian as well).
New changeset 83fc701 by Miss Islington (bot) in branch '3.6': bpo-38576: Disallow control characters in hostnames in http.client (GH-18995) (GH-19002) 83fc701
If anyone cares about 2.7, the *final* release is coming up in a few weeks. They'll need to figure out what it looks like there and get a 2.7 PR reviewed by the release manager.
New changeset e176e0c by Matěj Cepl in branch '2.7':
[2.7] closes bpo-38576: Disallow control characters in hostnames in http.client. (GH-19052) e176e0c
New changeset 09d8172 by Tapas Kundu in branch '3.5':
[3.5] closes bpo-38576: Disallow control characters in hostnames in http.client. (bpo-19300) 09d8172
Activity
ret2libc commentedon Oct 24, 2019
Copy-pasted from https://bugs.python.org/issue30458#msg347282
================
The commit b7378d7 is incomplete: it doesn't seem to check for control characters in the "host" part of the URL, only in the "path" part of the URL. Example:
---
try:
from urllib import request as urllib_request
except ImportError:
import urllib2 as urllib_request
import socket
def bug(*args):
raise Exception(args)
# urlopen() must not call create_connection()
socket.create_connection = bug
urllib_request.urlopen('http://127.0.0.1\\r\\n\\x20hihi\\r\\n :11211')
---
The URL comes from the first message of this issue:
https://bugs.python.org/issue30458#msg294360
Development branches 2.7 and master produce a similar output:
---
So urllib2/urllib.request actually does a real network connection (DNS query), whereas it should reject control characters in the "host" part of the URL.
A second problem comes into the game. Some C libraries like glibc strip the end of the hostname (strip at the first newline character) and so HTTP Header injection is still possible is this case:
https://bugzilla.redhat.com/show_bug.cgi?id=1673465
According to the RFC 3986, the "host" grammar doesn't allow any control character, it looks like:
ALPHA (letters)
DIGIT (decimal digits)
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
reg-name = *( unreserved / pct-encoded / sub-delims )
IP-literal = "[" ( IPv6address / IPvFuture ) "]"
IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
IPv6address = 6( h16 ":" ) ls32
/ "::" 5( h16 ":" ) ls32
/ [ h16 ] "::" 4( h16 ":" ) ls32
/ [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
/ [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
/ [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
/ [ *4( h16 ":" ) h16 ] "::" ls32
/ [ *5( h16 ":" ) h16 ] "::" h16
/ [ *6( h16 ":" ) h16 ] "::"
h16 = 1*4HEXDIG
ls32 = ( h16 ":" h16 ) / IPv4address
IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
================
CVE-2019-18348 was assigned to this flaw, which is similar to CVE-2019-9947 and CVE-2019-9740 but it is about the *host* part of a url.
[-]CVE-2019-18348 CRLF injection via the host part of the url passed to urlopen()[/-][+]CVE-2019-18348: CRLF injection via the host part of the url passed to urlopen()[/+]b1tninja commentedon Nov 20, 2019
Can't see the specifics of that "restricted" redhat bug, but this was interesting bug and I wanted to ask if perhaps the domain in such cases should be IDN / punycoded ://xn--n28h.ws/ for example is ://💩.la
ret2libc commentedon Nov 25, 2019
The glibc issue mentioned in the first comment is CVE-2016-10739 .
mcepl commentedon Feb 20, 2020
Just to say this is reproducible only on rather old enterprise Linux distributions, where CVE-2016-10739 bug in glibc has not been fixed. I believe it means RHEL-6, SUSE SLE-10, 11, 12 (not sure whether it applies to some old Debian as well).
gpshead commentedon Mar 14, 2020
New changeset 9165add by Ashwin Ramaswami in branch 'master':
bpo-38576: Disallow control characters in hostnames in http.client (GH-18995)
9165add
gpshead commentedon Mar 14, 2020
Thanks for the PR Ashwin!
miss-islington commentedon Mar 14, 2020
New changeset 34f85af by Miss Islington (bot) in branch '3.7':
bpo-38576: Disallow control characters in hostnames in http.client (GH-18995)
34f85af
miss-islington commentedon Mar 14, 2020
New changeset ff69c9d by Miss Islington (bot) in branch '3.8':
bpo-38576: Disallow control characters in hostnames in http.client (GH-18995)
ff69c9d
ned-deily commentedon Mar 14, 2020
New changeset 83fc701 by Miss Islington (bot) in branch '3.6':
bpo-38576: Disallow control characters in hostnames in http.client (GH-18995) (GH-19002)
83fc701
gpshead commentedon Mar 15, 2020
If anyone cares about 2.7, the *final* release is coming up in a few weeks. They'll need to figure out what it looks like there and get a 2.7 PR reviewed by the release manager.
gpshead commentedon Mar 18, 2020
marking as a 2.7 release blocker just to get benjamin's RM attention before the final 2.7.
benjaminp commentedon Mar 19, 2020
New changeset e176e0c by Matěj Cepl in branch '2.7':
[2.7] closes bpo-38576: Disallow control characters in hostnames in http.client. (GH-19052)
e176e0c
larryhastings commentedon Jun 20, 2020
New changeset 09d8172 by Tapas Kundu in branch '3.5':
[3.5] closes bpo-38576: Disallow control characters in hostnames in http.client. (bpo-19300)
09d8172