A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/c4e5ff7fdb5fce447675e90291fd33fddd052b3c below:

[2.1.x] Fixed CVE-2018-14574 -- Fixed open redirect possibility in Co… · django/django@c4e5ff7 · GitHub

File tree Expand file treeCollapse file tree 8 files changed

+78

-8

lines changed

Filter options

Expand file treeCollapse file tree 8 files changed

+78

-8

lines changed Original file line number Diff line number Diff line change

@@ -7,6 +7,7 @@

7 7

from django.http import HttpResponsePermanentRedirect

8 8

from django.urls import is_valid_path

9 9

from django.utils.deprecation import MiddlewareMixin

10 +

from django.utils.http import escape_leading_slashes

10 11 11 12 12 13

class CommonMiddleware(MiddlewareMixin):

@@ -79,6 +80,8 @@ def get_full_path_with_slash(self, request):

79 80

POST, PUT, or PATCH.

80 81

"""

81 82

new_path = request.get_full_path(force_append_slash=True)

83 +

# Prevent construction of scheme relative urls.

84 +

new_path = escape_leading_slashes(new_path)

82 85

if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):

83 86

raise RuntimeError(

84 87

"You called this URL via %(method)s, but the URL doesn't end "

Original file line number Diff line number Diff line change

@@ -17,7 +17,7 @@

17 17

from django.core.exceptions import ImproperlyConfigured

18 18

from django.utils.datastructures import MultiValueDict

19 19

from django.utils.functional import cached_property

20 -

from django.utils.http import RFC3986_SUBDELIMS

20 +

from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes

21 21

from django.utils.regex_helper import normalize

22 22

from django.utils.translation import get_language

23 23

@@ -592,9 +592,7 @@ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):

592 592

# safe characters from `pchar` definition of RFC 3986

593 593

url = quote(candidate_pat % text_candidate_subs, safe=RFC3986_SUBDELIMS + '/~:@')

594 594

# Don't allow construction of scheme relative urls.

595 -

if url.startswith('//'):

596 -

url = '/%%2F%s' % url[2:]

597 -

return url

595 +

return escape_leading_slashes(url)

598 596

# lookup_view can be URL name or callable, but callables are not

599 597

# friendly in error messages.

600 598

m = getattr(lookup_view, '__module__', None)

Original file line number Diff line number Diff line change

@@ -433,3 +433,14 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8',

433 433

value = unquote(value, encoding=encoding, errors=errors)

434 434

r.append((name, value))

435 435

return r

436 + 437 + 438 +

def escape_leading_slashes(url):

439 +

"""

440 +

If redirecting to an absolute path (two leading slashes), a slash must be

441 +

escaped to prevent browsers from handling the path as schemaless and

442 +

redirecting to another host.

443 +

"""

444 +

if url.startswith('//'):

445 +

url = '/%2F{}'.format(url[2:])

446 +

return url

Original file line number Diff line number Diff line change

@@ -5,3 +5,16 @@ Django 1.11.15 release notes

5 5

*August 1, 2018*

6 6 7 7

Django 1.11.15 fixes a security issue in 1.11.14.

8 + 9 +

CVE-2018-14574: Open redirect possibility in ``CommonMiddleware``

10 +

=================================================================

11 + 12 +

If the :class:`~django.middleware.common.CommonMiddleware` and the

13 +

:setting:`APPEND_SLASH` setting are both enabled, and if the project has a

14 +

URL pattern that accepts any path ending in a slash (many content management

15 +

systems have such a pattern), then a request to a maliciously crafted URL of

16 +

that site could lead to a redirect to another site, enabling phishing and other

17 +

attacks.

18 + 19 +

``CommonMiddleware`` now escapes leading slashes to prevent redirects to other

20 +

domains.

Original file line number Diff line number Diff line change

@@ -6,6 +6,19 @@ Django 2.0.8 release notes

6 6 7 7

Django 2.0.8 fixes a security issue and several bugs in 2.0.7.

8 8 9 +

CVE-2018-14574: Open redirect possibility in ``CommonMiddleware``

10 +

=================================================================

11 + 12 +

If the :class:`~django.middleware.common.CommonMiddleware` and the

13 +

:setting:`APPEND_SLASH` setting are both enabled, and if the project has a

14 +

URL pattern that accepts any path ending in a slash (many content management

15 +

systems have such a pattern), then a request to a maliciously crafted URL of

16 +

that site could lead to a redirect to another site, enabling phishing and other

17 +

attacks.

18 + 19 +

``CommonMiddleware`` now escapes leading slashes to prevent redirects to other

20 +

domains.

21 + 9 22

Bugfixes

10 23

========

11 24 Original file line number Diff line number Diff line change

@@ -130,6 +130,25 @@ def test_append_slash_quoted(self):

130 130

self.assertEqual(r.status_code, 301)

131 131

self.assertEqual(r.url, '/needsquoting%23/')

132 132 133 +

@override_settings(APPEND_SLASH=True)

134 +

def test_append_slash_leading_slashes(self):

135 +

"""

136 +

Paths starting with two slashes are escaped to prevent open redirects.

137 +

If there's a URL pattern that allows paths to start with two slashes, a

138 +

request with path //evil.com must not redirect to //evil.com/ (appended

139 +

slash) which is a schemaless absolute URL. The browser would navigate

140 +

to evil.com/.

141 +

"""

142 +

# Use 4 slashes because of RequestFactory behavior.

143 +

request = self.rf.get('////evil.com/security')

144 +

response = HttpResponseNotFound()

145 +

r = CommonMiddleware().process_request(request)

146 +

self.assertEqual(r.status_code, 301)

147 +

self.assertEqual(r.url, '/%2Fevil.com/security/')

148 +

r = CommonMiddleware().process_response(request, response)

149 +

self.assertEqual(r.status_code, 301)

150 +

self.assertEqual(r.url, '/%2Fevil.com/security/')

151 + 133 152

@override_settings(APPEND_SLASH=False, PREPEND_WWW=True)

134 153

def test_prepend_www(self):

135 154

request = self.rf.get('/path/')

Original file line number Diff line number Diff line change

@@ -6,4 +6,6 @@

6 6

url(r'^noslash$', views.empty_view),

7 7

url(r'^slash/$', views.empty_view),

8 8

url(r'^needsquoting#/$', views.empty_view),

9 +

# Accepts paths with two leading slashes.

10 +

url(r'^(.+)/security/$', views.empty_view),

9 11

]

Original file line number Diff line number Diff line change

@@ -5,10 +5,10 @@

5 5

from django.utils.datastructures import MultiValueDict

6 6

from django.utils.deprecation import RemovedInDjango30Warning

7 7

from django.utils.http import (

8 -

base36_to_int, cookie_date, http_date, int_to_base36, is_safe_url,

9 -

is_same_domain, parse_etags, parse_http_date, quote_etag, urlencode,

10 -

urlquote, urlquote_plus, urlsafe_base64_decode, urlsafe_base64_encode,

11 -

urlunquote, urlunquote_plus,

8 +

base36_to_int, cookie_date, escape_leading_slashes, http_date,

9 +

int_to_base36, is_safe_url, is_same_domain, parse_etags, parse_http_date,

10 +

quote_etag, urlencode, urlquote, urlquote_plus, urlsafe_base64_decode,

11 +

urlsafe_base64_encode, urlunquote, urlunquote_plus,

12 12

)

13 13 14 14

@@ -271,3 +271,14 @@ def test_parsing_rfc850(self):

271 271

def test_parsing_asctime(self):

272 272

parsed = parse_http_date('Sun Nov 6 08:49:37 1994')

273 273

self.assertEqual(datetime.utcfromtimestamp(parsed), datetime(1994, 11, 6, 8, 49, 37))

274 + 275 + 276 +

class EscapeLeadingSlashesTests(unittest.TestCase):

277 +

def test(self):

278 +

tests = (

279 +

('//example.com', '/%2Fexample.com'),

280 +

('//', '/%2F'),

281 +

)

282 +

for url, expected in tests:

283 +

with self.subTest(url=url):

284 +

self.assertEqual(escape_leading_slashes(url), expected)

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4