Commit c81a7c62 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of service...

Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of service using certificates with many wildcards (CVE-2013-2099).
parent 0d698df0
...@@ -108,9 +108,16 @@ class CertificateError(ValueError): ...@@ -108,9 +108,16 @@ class CertificateError(ValueError):
pass pass
def _dnsname_to_pat(dn): def _dnsname_to_pat(dn, max_wildcards=1):
pats = [] pats = []
for frag in dn.split(r'.'): for frag in dn.split(r'.'):
if frag.count('*') > max_wildcards:
# Issue #17980: avoid denials of service by refusing more
# than one wildcard per fragment. A survery of established
# policy among SSL implementations showed it to be a
# reasonable choice.
raise CertificateError(
"too many wildcards in certificate DNS name: " + repr(dn))
if frag == '*': if frag == '*':
# When '*' is a fragment by itself, it matches a non-empty dotless # When '*' is a fragment by itself, it matches a non-empty dotless
# fragment. # fragment.
......
...@@ -326,6 +326,17 @@ class BasicSocketTests(unittest.TestCase): ...@@ -326,6 +326,17 @@ class BasicSocketTests(unittest.TestCase):
self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
# Issue #17980: avoid denials of service by refusing more than one
# wildcard per fragment.
cert = {'subject': ((('commonName', 'a*b.com'),),)}
ok(cert, 'axxb.com')
cert = {'subject': ((('commonName', 'a*b.co*'),),)}
ok(cert, 'axxb.com')
cert = {'subject': ((('commonName', 'a*b*.com'),),)}
with self.assertRaises(ssl.CertificateError) as cm:
ssl.match_hostname(cert, 'axxbxxc.com')
self.assertIn("too many wildcards", str(cm.exception))
def test_server_side(self): def test_server_side(self):
# server_hostname doesn't work for server sockets # server_hostname doesn't work for server sockets
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
......
...@@ -10,6 +10,9 @@ What's New in Python 3.2.5? ...@@ -10,6 +10,9 @@ What's New in Python 3.2.5?
Library Library
------- -------
- Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of
service using certificates with many wildcards (CVE-2013-2099).
- Issue #17192: Restore the patch for Issue #11729 and Issue #10309 - Issue #17192: Restore the patch for Issue #11729 and Issue #10309
which were omitted in 3.2.4 when updating the bundled version of which were omitted in 3.2.4 when updating the bundled version of
libffi used by ctypes. libffi used by ctypes.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment