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

Skip to content

Commit 7cf7d74

Browse files
apollo13felixxm
authored andcommitted
[2.2.x] Fixed #30530, CVE-2021-44420 -- Fixed potential bypass of an upstream access control based on URL paths.
Thanks Sjoerd Job Postmus and TengMA(@te3t123) for reports. Backport of d4dcd5b from main.
1 parent 0007a5f commit 7cf7d74

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

django/urls/resolvers.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ def __init__(self, regex, name=None, is_endpoint=False):
147147
self.converters = {}
148148

149149
def match(self, path):
150-
match = self.regex.search(path)
150+
match = (
151+
self.regex.fullmatch(path)
152+
if self._is_endpoint and self.regex.pattern.endswith('$')
153+
else self.regex.search(path)
154+
)
151155
if match:
152156
# If there are any named groups, use those as kwargs, ignoring
153157
# non-named groups. Otherwise, pass all non-named arguments as
@@ -230,7 +234,7 @@ def _route_to_regex(route, is_endpoint=False):
230234
converters[parameter] = converter
231235
parts.append('(?P<' + parameter + '>' + converter.regex + ')')
232236
if is_endpoint:
233-
parts.append('$')
237+
parts.append(r'\Z')
234238
return ''.join(parts), converters
235239

236240

docs/releases/2.2.25.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ Django 2.2.25 release notes
66

77
Django 2.2.25 fixes a security issue with severity "low" in 2.2.24.
88

9-
...
9+
CVE-2021-44420: Potential bypass of an upstream access control based on URL paths
10+
=================================================================================
11+
12+
HTTP requests for URLs with trailing newlines could bypass an upstream access
13+
control based on URL paths.

tests/urlpatterns/tests.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,19 @@ def test_invalid_converter(self):
116116
with self.assertRaisesMessage(ImproperlyConfigured, msg):
117117
path('foo/<nonexistent:var>/', empty_view)
118118

119+
def test_path_trailing_newlines(self):
120+
tests = [
121+
'/articles/2003/\n',
122+
'/articles/2010/\n',
123+
'/en/foo/\n',
124+
'/included_urls/extra/\n',
125+
'/regex/1/\n',
126+
'/users/1/\n',
127+
]
128+
for url in tests:
129+
with self.subTest(url=url), self.assertRaises(Resolver404):
130+
resolve(url)
131+
119132

120133
@override_settings(ROOT_URLCONF='urlpatterns.converter_urls')
121134
class ConverterTests(SimpleTestCase):

0 commit comments

Comments
 (0)