Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4452642

Browse files
ngnpopefelixxm
authored andcommitted
[4.0.x] FixedCVE-2023-23969 -- Prevented DoS with pathological values for Accept-Language.
The parsed values of Accept-Language headers are cached in order toavoid repetitive parsing. This leads to a potential denial-of-servicevector via excessive memory usage if the raw value of Accept-Languageheaders is very large.Accept-Language headers are now limited to a maximum length in orderto avoid this issue.
1 parentb880e20 commit4452642

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

‎django/utils/translation/trans_real.py‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
# magic gettext number to separate context from message
3131
CONTEXT_SEPARATOR="\x04"
3232

33+
# Maximum number of characters that will be parsed from the Accept-Language
34+
# header to prevent possible denial of service or memory exhaustion attacks.
35+
# About 10x longer than the longest value shown on MDN’s Accept-Language page.
36+
ACCEPT_LANGUAGE_HEADER_MAX_LENGTH=500
37+
3338
# Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9
3439
# and RFC 3066, section 2.1
3540
accept_language_re=_lazy_re_compile(
@@ -585,7 +590,7 @@ def get_language_from_request(request, check_path=False):
585590

586591

587592
@functools.lru_cache(maxsize=1000)
588-
defparse_accept_lang_header(lang_string):
593+
def_parse_accept_lang_header(lang_string):
589594
"""
590595
Parse the lang_string, which is the body of an HTTP Accept-Language
591596
header, and return a tuple of (lang, q-value), ordered by 'q' values.
@@ -607,3 +612,27 @@ def parse_accept_lang_header(lang_string):
607612
result.append((lang,priority))
608613
result.sort(key=lambdak:k[1],reverse=True)
609614
returntuple(result)
615+
616+
617+
defparse_accept_lang_header(lang_string):
618+
"""
619+
Parse the value of the Accept-Language header up to a maximum length.
620+
621+
The value of the header is truncated to a maximum length to avoid potential
622+
denial of service and memory exhaustion attacks. Excessive memory could be
623+
used if the raw value is very large as it would be cached due to the use of
624+
functools.lru_cache() to avoid repetitive parsing of common header values.
625+
"""
626+
# If the header value doesn't exceed the maximum allowed length, parse it.
627+
iflen(lang_string)<=ACCEPT_LANGUAGE_HEADER_MAX_LENGTH:
628+
return_parse_accept_lang_header(lang_string)
629+
630+
# If there is at least one comma in the value, parse up to the last comma
631+
# before the max length, skipping any truncated parts at the end of the
632+
# header value.
633+
if (index:=lang_string.rfind(",",0,ACCEPT_LANGUAGE_HEADER_MAX_LENGTH))>0:
634+
return_parse_accept_lang_header(lang_string[:index])
635+
636+
# Don't attempt to parse if there is only one language-range value which is
637+
# longer than the maximum allowed length and so truncated.
638+
return ()

‎docs/releases/3.2.17.txt‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,12 @@ Django 3.2.17 release notes
66

77
Django 3.2.17 fixes a security issue with severity "moderate" in 3.2.16.
88

9-
...
9+
CVE-2023-23969: Potential denial-of-service via ``Accept-Language`` headers
10+
===========================================================================
11+
12+
The parsed values of ``Accept-Language`` headers are cached in order to avoid
13+
repetitive parsing. This leads to a potential denial-of-service vector via
14+
excessive memory usage if large header values are sent.
15+
16+
In order to avoid this vulnerability, the ``Accept-Language`` header is now
17+
parsed up to a maximum length.

‎docs/releases/4.0.9.txt‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,12 @@ Django 4.0.9 release notes
66

77
Django 4.0.9 fixes a security issue with severity "moderate" in 4.0.8.
88

9-
...
9+
CVE-2023-23969: Potential denial-of-service via ``Accept-Language`` headers
10+
===========================================================================
11+
12+
The parsed values of ``Accept-Language`` headers are cached in order to avoid
13+
repetitive parsing. This leads to a potential denial-of-service vector via
14+
excessive memory usage if large header values are sent.
15+
16+
In order to avoid this vulnerability, the ``Accept-Language`` header is now
17+
parsed up to a maximum length.

‎tests/i18n/tests.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,14 @@ def test_parse_spec_http_header(self):
17281728
("de;q=0.", [("de",0.0)]),
17291729
("en; q=1,", [("en",1.0)]),
17301730
("en; q=1.0, * ; q=0.5", [("en",1.0), ("*",0.5)]),
1731+
(
1732+
"en"+"-x"*20,
1733+
[("en-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x",1.0)],
1734+
),
1735+
(
1736+
", ".join(["en; q=1.0"]*20),
1737+
[("en",1.0)]*20,
1738+
),
17311739
# Bad headers
17321740
("en-gb;q=1.0000", []),
17331741
("en;q=0.1234", []),
@@ -1743,6 +1751,11 @@ def test_parse_spec_http_header(self):
17431751
("12-345", []),
17441752
("", []),
17451753
("en;q=1e0", []),
1754+
("en-au;q=1.0", []),
1755+
# Invalid as language-range value too long.
1756+
("xxxxxxxx"+"-xxxxxxxx"*500, []),
1757+
# Header value too long, only parse up to limit.
1758+
(", ".join(["en; q=1.0"]*500), [("en",1.0)]*45),
17461759
]
17471760
forvalue,expectedintests:
17481761
withself.subTest(value=value):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp