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-2013-2099 ssl.match_hostname() trips over crafted wildcard names #62180
If the name in the certificate contains many "*" characters, matching the compiled regular expression against the host name can take a very long time. Certificate validation happens before host name checking, so I think this is a minor issue only because it can only be triggered in cooperation with a CA (which seems unlikely).
The fix is to limit the number of "*" wildcards to a reasonable maximum (perhaps even 1).
changed the title [-]ssl.match_hostname() trips over crafted wildcard names[/-][+]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/+]on May 16, 2013
I would like to know what is the expected scenario:
does the attacker only control the certificate?
or does the attacker control both the certificate and the hostname being validated?
The reason is that the matching cost for a domain name fragment seems to be O(n**k), where n is the fragment length and k is the number of wildcards. Therefore, if the attacker controls both n and k, even limiting k to 2 already allows a quadratic complexity attack.
RFC 2818 doesn't say anything about the maximum amount of wildcards. I'm going to check OpenSSL's implementation now.
fweimer commented on May 16, 2013
fweimermannequin
MannequinAuthor
More actions
OpenSSL supports only a single wildcard character.
In my tests, I used a host name like aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.org, and a dNSName like a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*.example.org. Quadratic behavior wouldn't be too bad because the host name is necessarily rather short (more than 255 characters will not pass through DNS).
In my tests, I used a host name like
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.org, and a dNSName
like a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*.example.org.
Quadratic behavior wouldn't be too bad because the host name is
necessarily rather short (more than 255 characters will not pass
through DNS).
Hmm, but the host name doesn't necessarily come from DNS, does it?
changed the title [-]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/-][+]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/+]on May 16, 2013
fweimer commented on May 16, 2013
fweimermannequin
MannequinAuthor
More actions
The host name is looked up to get the IP address to connect to. The lookup will fail if the host name is longer than 255 characters, and the crafted certificate is never retrieved.
Florian, I'm actually surprised by your assertion that OpenSSL supports a single wildcard character. Last I looked, I couldn't find any hostname matching function in OpenSSL (which is why I had to write our own). Could you point me to the relevant piece of code?
I still think that sub string wildcard should not match the IDN "xn--" prefix. With current code the rules "x*.example.de" gives a positive match for "götter.example.de".
I still think that sub string wildcard should not match the IDN
"xn--" prefix. With current code the rules "x*.example.de" gives a
positive match for "götter.example.de".
You should open a separate issue for this (possibly with a patch).
Activity
fweimer commentedon May 15, 2013
If the name in the certificate contains many "*" characters, matching the compiled regular expression against the host name can take a very long time. Certificate validation happens before host name checking, so I think this is a minor issue only because it can only be triggered in cooperation with a CA (which seems unlikely).
The fix is to limit the number of "*" wildcards to a reasonable maximum (perhaps even 1).
pitrou commentedon May 15, 2013
Does the RFC say anything about this? How much wildcards are necessary to take up a significant amount of CPU time?
iankko commentedon May 16, 2013
The CVE identifier of CVE-2013-2099 has been assigned:
http://www.openwall.com/lists/oss-security/2013/05/16/6
to this issue.
[-]ssl.match_hostname() trips over crafted wildcard names[/-][+]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/+]pitrou commentedon May 16, 2013
This is caused by the regex engine's performance behaviour:
http://bugs.python.org/issue1662581
http://bugs.python.org/issue1515829
http://bugs.python.org/issue212521
pitrou commentedon May 16, 2013
I would like to know what is the expected scenario:
The reason is that the matching cost for a domain name fragment seems to be O(n**k), where n is the fragment length and k is the number of wildcards. Therefore, if the attacker controls both n and k, even limiting k to 2 already allows a quadratic complexity attack.
tiran commentedon May 16, 2013
RFC 2818 doesn't say anything about the maximum amount of wildcards. I'm going to check OpenSSL's implementation now.
fweimer commentedon May 16, 2013
OpenSSL supports only a single wildcard character.
In my tests, I used a host name like aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.org, and a dNSName like a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*.example.org. Quadratic behavior wouldn't be too bad because the host name is necessarily rather short (more than 255 characters will not pass through DNS).
pitrou commentedon May 16, 2013
Indeed, two wildcards seem to be ok with a 255-character domain name:
Three wildcards already start producing some load:
Four wildcards are more than enough for a DoS:
pitrou commentedon May 16, 2013
Hmm, but the host name doesn't necessarily come from DNS, does it?
[-]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/-][+]CVE-2013-2099 ssl.match_hostname() trips over crafted wildcard names[/+]fweimer commentedon May 16, 2013
The host name is looked up to get the IP address to connect to. The lookup will fail if the host name is longer than 255 characters, and the crafted certificate is never retrieved.
tiran commentedon May 16, 2013
I think a malicious user could abuse SNI to craft a longer host name and trigger the pathological case.
11 remaining items
pitrou commentedon May 17, 2013
Non-greedy matching actually makes things worse :-)
pitrou commentedon May 17, 2013
Florian, I'm actually surprised by your assertion that OpenSSL supports a single wildcard character. Last I looked, I couldn't find any hostname matching function in OpenSSL (which is why I had to write our own). Could you point me to the relevant piece of code?
fweimer commentedon May 17, 2013
Antoine, support for OpenSSL host name matching is quite new: <http://www.openssl.org/docs/crypto/X509_check_host.html\>
pitrou commentedon May 17, 2013
libcurl supports a single wildcard for the whole domain name pattern (not even one per fragment), as per lib/hostcheck.c
(this is when linked against OpenSSL; when linked against GnuTLS, curl will use the GnuTLS-provided matching function)
Based on all the evidence, I think allowing one wildcard per fragment is sufficient.
pitrou commentedon May 17, 2013
Ah, thanks. I was looking in 1.0.1e.
malemburg commentedon May 17, 2013
Here's another long discussions about SSL hostname matching that may provide some useful insights:
Note how RFC 2595 doesn't even allow sub-string matching. It only allows '*' to be used as component.
pitrou commentedon May 17, 2013
Attached patch forbidding more than one wildcard per fragment.
tiran commentedon May 17, 2013
I still think that sub string wildcard should not match the IDN "xn--" prefix. With current code the rules "x*.example.de" gives a positive match for "götter.example.de".
pitrou commentedon May 17, 2013
You should open a separate issue for this (possibly with a patch).
tiran commentedon May 17, 2013
bpo-17997
tiran commentedon May 18, 2013
The IDNA RFC contains additional rules for wildcard matching ... very well hidden indead!
http://tools.ietf.org/html/rfc6125#section-6.4.3
python-dev commentedon May 18, 2013
New changeset b9b521efeba3 by Antoine Pitrou in branch '3.2':
Issue bpo-17980: Fix possible abuse of ssl.match_hostname() for denial of service using certificates with many wildcards (CVE-2013-2099).
http://hg.python.org/cpython/rev/b9b521efeba3
New changeset c627638753e2 by Antoine Pitrou in branch '3.3':
Issue bpo-17980: Fix possible abuse of ssl.match_hostname() for denial of service using certificates with many wildcards (CVE-2013-2099).
http://hg.python.org/cpython/rev/c627638753e2
New changeset fafd33db6ff6 by Antoine Pitrou in branch 'default':
Issue bpo-17980: Fix possible abuse of ssl.match_hostname() for denial of service using certificates with many wildcards (CVE-2013-2099).
http://hg.python.org/cpython/rev/fafd33db6ff6
pitrou commentedon May 18, 2013
Ok, this should be fixed now. Thanks a lot for reporting!