Date: Friday, April 15, 2011 @ 08:17:53 Author: stephane Revision: 119810
upgpkg: python2 2.7.1-9 urllib security vulnerability fixed (CVE-2011-1521) Added: python2/trunk/CVE-2011-1521.patch python2/trunk/python-2.7-db51.patch (from rev 119809, python2/trunk/python-2.7-db51.diff) Modified: python2/trunk/PKGBUILD Deleted: python2/trunk/python-2.7-db51.diff -----------------------+ CVE-2011-1521.patch | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD | 20 ++++++--- python-2.7-db51.diff | 42 -------------------- python-2.7-db51.patch | 42 ++++++++++++++++++++ 4 files changed, 153 insertions(+), 49 deletions(-) Added: CVE-2011-1521.patch =================================================================== --- CVE-2011-1521.patch (rev 0) +++ CVE-2011-1521.patch 2011-04-15 12:17:53 UTC (rev 119810) @@ -0,0 +1,98 @@ +diff -Naur Python-2.7.1.ori/Lib/test/test_urllib2.py Python-2.7.1/Lib/test/test_urllib2.py +--- Python-2.7.1.ori/Lib/test/test_urllib2.py 2010-11-21 21:04:33.000000000 -0800 ++++ Python-2.7.1/Lib/test/test_urllib2.py 2011-04-15 05:02:13.278853672 -0700 +@@ -969,6 +969,27 @@ + 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) ++ ++ 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 -Naur Python-2.7.1.ori/Lib/test/test_urllib.py Python-2.7.1/Lib/test/test_urllib.py +--- Python-2.7.1.ori/Lib/test/test_urllib.py 2010-11-21 05:34:58.000000000 -0800 ++++ Python-2.7.1/Lib/test/test_urllib.py 2011-04-15 05:02:13.278853672 -0700 +@@ -161,6 +161,20 @@ + 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) +diff -Naur Python-2.7.1.ori/Lib/urllib2.py Python-2.7.1/Lib/urllib2.py +--- Python-2.7.1.ori/Lib/urllib2.py 2010-11-20 03:24:08.000000000 -0800 ++++ Python-2.7.1/Lib/urllib2.py 2011-04-15 05:02:13.278853672 -0700 +@@ -579,6 +579,17 @@ + + 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 -Naur Python-2.7.1.ori/Lib/urllib.py Python-2.7.1/Lib/urllib.py +--- Python-2.7.1.ori/Lib/urllib.py 2010-11-21 21:04:33.000000000 -0800 ++++ Python-2.7.1/Lib/urllib.py 2011-04-15 05:02:13.278853672 -0700 +@@ -644,6 +644,18 @@ + fp.close() + # In case the server sent a relative URL, join with original: + newurl = basejoin(self.type + ":" + 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 IOError('redirect error', errcode, ++ errmsg + " - Redirection to url '%s' is not allowed" % ++ newurl, ++ headers) ++ + return self.open(newurl) + + def http_error_301(self, url, fp, errcode, errmsg, headers, data=None): Modified: PKGBUILD =================================================================== --- PKGBUILD 2011-04-15 11:51:54 UTC (rev 119809) +++ PKGBUILD 2011-04-15 12:17:53 UTC (rev 119810) @@ -5,7 +5,7 @@ pkgname=python2 pkgver=2.7.1 -pkgrel=8 +pkgrel=9 _pybasever=2.7 pkgdesc="A high-level scripting language" arch=('i686' 'x86_64') @@ -17,17 +17,23 @@ conflicts=('python<3') options=('!makeflags') source=(http://www.python.org/ftp/python/${pkgver}/Python-${pkgver}.tar.bz2 - python-2.7-db51.diff - python-2.7.1-fix-decimal-in-turkish-locale.patch) -md5sums=('aa27bc25725137ba155910bd8e5ddc4f' - 'd9b8161568ce17a305c1b71e61ccd4b5' - '5032449f1ff2abfe18d14cc674165b23') + CVE-2011-1521.patch + python-2.7.1-fix-decimal-in-turkish-locale.patch + python-2.7-db51.patch) +sha1sums=('fbe1894322ff91b80726e269c97454f4129fc2a3' + '31cdc76092d0f598289aaeb18e492874c981904d' + 'baf470682ae7d2b55caaa173696d08d3f468a569' + '9667a2a2f8594902b352793e649f78696a77bd13') build() { cd "${srcdir}/Python-${pkgver}" - patch -Np1 -i ../python-2.7-db51.diff + patch -Np1 -i ../python-2.7-db51.patch + # Fix urllib Security Vulnerability + # http://blog.python.org/2011/04/urllib-security-vulnerability-fixed.html + patch -Np1 -i ../CVE-2011-1521.patch + # Fix "import decimal" in the Turkish locale # cf : https://bugzilla.redhat.com/show_bug.cgi?id=694928 patch -Np1 -i ../python-2.7.1-fix-decimal-in-turkish-locale.patch Deleted: python-2.7-db51.diff =================================================================== --- python-2.7-db51.diff 2011-04-15 11:51:54 UTC (rev 119809) +++ python-2.7-db51.diff 2011-04-15 12:17:53 UTC (rev 119810) @@ -1,42 +0,0 @@ -diff -Naur Python-2.7-orig//Modules/_bsddb.c Python-2.7/Modules/_bsddb.c ---- Python-2.7-orig//Modules/_bsddb.c 2010-05-10 00:46:46.000000000 +1000 -+++ Python-2.7/Modules/_bsddb.c 2010-10-20 13:19:26.436669911 +1000 -@@ -9765,8 +9765,11 @@ - - ADD_INT(d, DB_REP_PERMANENT); - --#if (DBVER >= 44) -+#if (DBVER >= 44) && (DBVER <= 48) - ADD_INT(d, DB_REP_CONF_NOAUTOINIT); -+#endif -+ -+#if (DBVER >= 44) - ADD_INT(d, DB_REP_CONF_DELAYCLIENT); - ADD_INT(d, DB_REP_CONF_BULK); - ADD_INT(d, DB_REP_CONF_NOWAIT); -diff -Naur Python-2.7-orig//setup.py Python-2.7/setup.py ---- Python-2.7-orig//setup.py 2010-06-27 22:36:16.000000000 +1000 -+++ Python-2.7/setup.py 2010-10-20 13:10:48.256670026 +1000 -@@ -765,7 +765,7 @@ - # a release. Most open source OSes come with one or more - # versions of BerkeleyDB already installed. - -- max_db_ver = (4, 8) -+ max_db_ver = (5, 1) - min_db_ver = (4, 1) - db_setup_debug = False # verbose debug prints from this script? - -@@ -787,8 +787,12 @@ - return True - - def gen_db_minor_ver_nums(major): -- if major == 4: -+ if major == 5: - for x in range(max_db_ver[1]+1): -+ if allow_db_ver((5, x)): -+ yield x -+ if major == 4: -+ for x in range(9): - if allow_db_ver((4, x)): - yield x - elif major == 3: Copied: python2/trunk/python-2.7-db51.patch (from rev 119809, python2/trunk/python-2.7-db51.diff) =================================================================== --- python-2.7-db51.patch (rev 0) +++ python-2.7-db51.patch 2011-04-15 12:17:53 UTC (rev 119810) @@ -0,0 +1,42 @@ +diff -Naur Python-2.7-orig//Modules/_bsddb.c Python-2.7/Modules/_bsddb.c +--- Python-2.7-orig//Modules/_bsddb.c 2010-05-10 00:46:46.000000000 +1000 ++++ Python-2.7/Modules/_bsddb.c 2010-10-20 13:19:26.436669911 +1000 +@@ -9765,8 +9765,11 @@ + + ADD_INT(d, DB_REP_PERMANENT); + +-#if (DBVER >= 44) ++#if (DBVER >= 44) && (DBVER <= 48) + ADD_INT(d, DB_REP_CONF_NOAUTOINIT); ++#endif ++ ++#if (DBVER >= 44) + ADD_INT(d, DB_REP_CONF_DELAYCLIENT); + ADD_INT(d, DB_REP_CONF_BULK); + ADD_INT(d, DB_REP_CONF_NOWAIT); +diff -Naur Python-2.7-orig//setup.py Python-2.7/setup.py +--- Python-2.7-orig//setup.py 2010-06-27 22:36:16.000000000 +1000 ++++ Python-2.7/setup.py 2010-10-20 13:10:48.256670026 +1000 +@@ -765,7 +765,7 @@ + # a release. Most open source OSes come with one or more + # versions of BerkeleyDB already installed. + +- max_db_ver = (4, 8) ++ max_db_ver = (5, 1) + min_db_ver = (4, 1) + db_setup_debug = False # verbose debug prints from this script? + +@@ -787,8 +787,12 @@ + return True + + def gen_db_minor_ver_nums(major): +- if major == 4: ++ if major == 5: + for x in range(max_db_ver[1]+1): ++ if allow_db_ver((5, x)): ++ yield x ++ if major == 4: ++ for x in range(9): + if allow_db_ver((4, x)): + yield x + elif major == 3: