]> granicus.if.org Git - python/commitdiff
Merge urllib/urllib2 security fix from 2.5 branch.
authorguido@google.com <guido@google.com>
Tue, 29 Mar 2011 17:48:23 +0000 (10:48 -0700)
committerguido@google.com <guido@google.com>
Tue, 29 Mar 2011 17:48:23 +0000 (10:48 -0700)
1  2 
Lib/test/test_urllib.py
Lib/test/test_urllib2.py
Lib/urllib.py
Lib/urllib2.py
Misc/NEWS

index 402309ce3e712101217ae6d28c3eec294c896b22,72db1ef29c14b6c7f799b50c9f90ec8a4d3abc0c..84b6f253ab74abaf7004227ace9091bf7ad4b88e
@@@ -162,9 -122,23 +162,23 @@@ Content-Type: text/html; charset=iso-88
          finally:
              self.unfakehttp()
  
+     def test_invalid_redirect(self):
+         # urlopen() should raise IOError for many error codes.
+         self.fakehttp("""HTTP/1.1 302 Found
+ Date: Wed, 02 Jan 2008 03:03:54 GMT
+ Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
+ Location: file:README
+ Connection: close
+ Content-Type: text/html; charset=iso-8859-1
+ """)
+         try:
+             self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
+         finally:
+             self.unfakehttp()
      def test_empty_socket(self):
 -        """urlopen() raises IOError if the underlying socket does not send any
 -        data. (#1680230) """
 +        urlopen() raises IOError if the underlying socket does not send any
 +        # data. (#1680230)
          self.fakehttp('')
          try:
              self.assertRaises(IOError, urllib.urlopen, 'http://something')
index 65ad8e307a2e3b1b698ee18b879412b4f414d9c9,8e9f1b2fef09e4e48a6fc2dcb66b9fd6159bf104..640c6616ca7ae15341a6b70607dd0a885cf580ac
@@@ -942,6 -857,27 +942,28 @@@ class HandlerTests(unittest.TestCase)
              self.assertEqual(count,
                               urllib2.HTTPRedirectHandler.max_redirections)
  
+     def test_invalid_redirect(self):
+         from_url = "http://example.com/a.html"
+         valid_schemes = ['http', 'https', 'ftp']
+         invalid_schemes = ['file', 'imap', 'ldap']
+         schemeless_url = "example.com/b.html"
+         h = urllib2.HTTPRedirectHandler()
+         o = h.parent = MockOpener()
+         req = Request(from_url)
++        req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
+         for scheme in invalid_schemes:
+             invalid_url = scheme + '://' + schemeless_url
+             self.assertRaises(urllib2.HTTPError, h.http_error_302,
+                               req, MockFile(), 302, "Security Loophole",
+                               MockHeaders({"location": invalid_url}))
+         for scheme in valid_schemes:
+             valid_url = scheme + '://' + schemeless_url
+             h.http_error_302(req, MockFile(), 302, "That's fine",
+                 MockHeaders({"location": valid_url}))
+             self.assertEqual(o.req.get_full_url(), valid_url)
      def test_cookie_redirect(self):
          # cookies shouldn't leak into redirected requests
          from cookielib import CookieJar
diff --cc Lib/urllib.py
Simple merge
diff --cc Lib/urllib2.py
index ca74c9f22d386dba513ec6201035a435a1f31a9c,a537d3630e7900276b996858de69c5ab12e2e254..2c1c0c5afc25855d5cff301a28a00ee74a7decad
@@@ -568,16 -553,19 +568,27 @@@ class HTTPRedirectHandler(BaseHandler)
              newurl = headers.getheaders('uri')[0]
          else:
              return
 +
 +        # fix a possible malformed URL
 +        urlparts = urlparse.urlparse(newurl)
 +        if not urlparts.path:
 +            urlparts = list(urlparts)
 +            urlparts[2] = "/"
 +        newurl = urlparse.urlunparse(urlparts)
 +
          newurl = urlparse.urljoin(req.get_full_url(), newurl)
  
+         # For security reasons we do not allow redirects to protocols
+         # other than HTTP, HTTPS or FTP.
+         newurl_lower = newurl.lower()
+         if not (newurl_lower.startswith('http://') or
+                 newurl_lower.startswith('https://') or
+                 newurl_lower.startswith('ftp://')):
+             raise HTTPError(newurl, code,
+                             msg + " - Redirection to url '%s' is not allowed" %
+                             newurl,
+                             headers, fp)
          # XXX Probably want to forget about the state of the current
          # request, although that might interact poorly with other
          # handlers that also use handler-specific request attributes
diff --cc Misc/NEWS
index 449348ef6f6120f32f68243cad7f0c9d6643e127,551ecb73abf2b7402c4498e1bf7418efacb0e51a..2819a69b0c898a84a11b2a69e1aff5ab7c84150f
+++ b/Misc/NEWS
@@@ -4,54 -4,34 +4,56 @@@ Python New
  
  (editors: check NEWS.help for information about editing NEWS using ReST.)
  
 -What's New in Python 2.5.6c1?
 -=============================
 +What's New in Python 2.6.7?
 +===========================
  
 -*Release date: XX-XXX-2010*
 +*Release date: XXXX-XX-XX*
  
 -Library
 --------
 +*NOTE: Python 2.6 is in security-fix-only mode.  No non-security bug fixes are
 + allowed.  Python 2.6.7 and beyond will be source only releases.*
  
+ - Issue #11662: Make urllib and urllib2 ignore redirections if the
+   scheme is not HTTP, HTTPS or FTP (CVE-2011-1521).
  
 -- Issue #8674: Fixed a number of incorrect or undefined-behaviour-inducing
 -  overflow checks in the audioop module (CVE-2010-1634).
 +Core and Builtins
 +-----------------
  
 -- Issue #7673: Fix security vulnerability (CVE-2010-2089) in the audioop
 -  module, ensure that the input string length is a multiple of the frame size.
 +Library
 +-------
  
 +- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
 +  error handling when accepting a new connection.
  
 -What's New in Python 2.5.5?
 +What's New in Python 2.6.6?
  ===========================
  
 -*Release date: 31-Jan-2010*
 +*Release date: 2010-08-24*
  
 +Core and Builtins
 +-----------------
  
 -What's New in Python 2.5.5c2?
 -=============================
 +Library
 +-------
 +
 +
 +What's New in Python 2.6.6 rc 2?
 +================================
  
 -*Release date: 24-Jan-2010*
 +*Release date: 2010-08-16*
 +
 +Library
 +-------
 +
 +- Issue #9600: Don't use relative import for _multiprocessing on Windows.
 +
 +- Issue #8688: Revert regression introduced in 2.6.6rc1 (making Distutils
 +  recalculate MANIFEST every time).
 +
 +- Issue #5798: Handle select.poll flag oddities properly on OS X.
 +  This fixes test_asynchat and test_smtplib failures on OS X.
 +
 +- Issue #9543: Fix regression in socket.py introduced in Python 2.6.6 rc 1
 +  in r83624.
  
  Extension Modules
  -----------------