Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d055956

Browse files
committed
Merge 3.1
2 parents 35722a9 + d6c1d57 commit d055956

6 files changed

Lines changed: 75 additions & 1 deletion

File tree

Doc/library/urllib.request.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,10 @@ HTTPRedirectHandler Objects
783783
is the case, :exc:`HTTPError` is raised. See :rfc:`2616` for details of the
784784
precise meanings of the various redirection codes.
785785

786+
An :class:`HTTPError` exception raised as a security consideration if the
787+
HTTPRedirectHandler is presented with a redirected url which is not an HTTP,
788+
HTTPS or FTP url.
789+
786790

787791
.. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)
788792

Lib/test/test_urllib.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import urllib.parse
44
import urllib.request
5+
import urllib.error
56
import http.client
67
import email.message
78
import io
@@ -183,6 +184,21 @@ def test_read_bogus(self):
183184
finally:
184185
self.unfakehttp()
185186

187+
def test_invalid_redirect(self):
188+
# urlopen() should raise IOError for many error codes.
189+
self.fakehttp(b'''HTTP/1.1 302 Found
190+
Date: Wed, 02 Jan 2008 03:03:54 GMT
191+
Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
192+
Location: file://guidocomputer.athome.com:/python/license
193+
Connection: close
194+
Content-Type: text/html; charset=iso-8859-1
195+
''')
196+
try:
197+
self.assertRaises(urllib.error.HTTPError, urlopen,
198+
"http://python.org/")
199+
finally:
200+
self.unfakehttp()
201+
186202
def test_empty_socket(self):
187203
# urlopen() raises IOError if the underlying socket does not send any
188204
# data. (#1680230)

Lib/test/test_urllib2.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# The proxy bypass method imported below has logic specific to the OSX
1010
# proxy config data structure but is testable on all platforms.
1111
from urllib.request import Request, OpenerDirector, _proxy_bypass_macosx_sysconf
12+
import urllib.error
1213

1314
# XXX
1415
# Request
@@ -985,6 +986,29 @@ def redirect(h, req, url=to_url):
985986
self.assertEqual(count,
986987
urllib.request.HTTPRedirectHandler.max_redirections)
987988

989+
990+
def test_invalid_redirect(self):
991+
from_url = "http://example.com/a.html"
992+
valid_schemes = ['http','https','ftp']
993+
invalid_schemes = ['file','imap','ldap']
994+
schemeless_url = "example.com/b.html"
995+
h = urllib.request.HTTPRedirectHandler()
996+
o = h.parent = MockOpener()
997+
req = Request(from_url)
998+
req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
999+
1000+
for scheme in invalid_schemes:
1001+
invalid_url = scheme + '://' + schemeless_url
1002+
self.assertRaises(urllib.error.HTTPError, h.http_error_302,
1003+
req, MockFile(), 302, "Security Loophole",
1004+
MockHeaders({"location": invalid_url}))
1005+
1006+
for scheme in valid_schemes:
1007+
valid_url = scheme + '://' + schemeless_url
1008+
h.http_error_302(req, MockFile(), 302, "That's fine",
1009+
MockHeaders({"location": valid_url}))
1010+
self.assertEqual(o.req.get_full_url(), valid_url)
1011+
9881012
def test_cookie_redirect(self):
9891013
# cookies shouldn't leak into redirected requests
9901014
from http.cookiejar import CookieJar

Lib/urllib/request.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,17 @@ def http_error_302(self, req, fp, code, msg, headers):
528528

529529
# fix a possible malformed URL
530530
urlparts = urlparse(newurl)
531+
532+
# For security reasons we don't allow redirection to anything other
533+
# than http, https or ftp.
534+
535+
if not urlparts.scheme in ('http', 'https', 'ftp'):
536+
raise HTTPError(newurl, code,
537+
msg +
538+
" - Redirection to url '%s' is not allowed" %
539+
newurl,
540+
headers, fp)
541+
531542
if not urlparts.path:
532543
urlparts = list(urlparts)
533544
urlparts[2] = "/"
@@ -1864,8 +1875,24 @@ def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
18641875
return
18651876
void = fp.read()
18661877
fp.close()
1878+
18671879
# In case the server sent a relative URL, join with original:
18681880
newurl = urljoin(self.type + ":" + url, newurl)
1881+
1882+
urlparts = urlparse(newurl)
1883+
1884+
# For security reasons, we don't allow redirection to anything other
1885+
# than http, https and ftp.
1886+
1887+
# We are using newer HTTPError with older redirect_internal method
1888+
# This older method will get deprecated in 3.3
1889+
1890+
if not urlparts.scheme in ('http', 'https', 'ftp'):
1891+
raise HTTPError(newurl, errcode,
1892+
errmsg +
1893+
" Redirection to url '%s' is not allowed." % newurl,
1894+
headers, fp)
1895+
18691896
return self.open(newurl)
18701897

18711898
def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ Library
5858
- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459.
5959
Patch by Ben Hayden.
6060

61+
- Issue #11662: Make urllib and urllib2 ignore redirections if the
62+
scheme is not HTTP, HTTPS or FTP (CVE-2011-1521).
63+
6164
- Issue #5537: Fix time2isoz() and time2netscape() functions of
6265
httplib.cookiejar for expiration year greater than 2038 on 32-bit systems.
6366

Modules/_collectionsmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ static PyMethodDef deque_methods[] = {
913913
PyDoc_STRVAR(deque_doc,
914914
"deque(iterable[, maxlen]) --> deque object\n\
915915
\n\
916-
Build an ordered collection accessible from endpoints only.");
916+
Build an ordered collection with optimized access from its endpoints.");
917917

918918
static PyTypeObject deque_type = {
919919
PyVarObject_HEAD_INIT(NULL, 0)

0 commit comments

Comments
 (0)