A RetroSearch Logo

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

Search Query:

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

[4.2.x] Fixed CVE-2024-39614 -- Mitigated potential DoS in get_suppor… · django/django@17358fb · GitHub

File tree Expand file treeCollapse file tree 4 files changed

+56

-5

lines changed

Filter options

Expand file treeCollapse file tree 4 files changed

+56

-5

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

@@ -31,9 +31,10 @@

31 31

CONTEXT_SEPARATOR = "\x04"

32 32 33 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

34 +

# header or cookie to prevent possible denial of service or memory exhaustion

35 +

# attacks. About 10x longer than the longest value shown on MDN’s

36 +

# Accept-Language page.

37 +

LANGUAGE_CODE_MAX_LENGTH = 500

37 38 38 39

# Format of Accept-Language header values. From RFC 9110 Sections 12.4.2 and

39 40

# 12.5.4, and RFC 5646 Section 2.1.

@@ -497,11 +498,25 @@ def get_supported_language_variant(lang_code, strict=False):

497 498

If `strict` is False (the default), look for a country-specific variant

498 499

when neither the language code nor its generic variant is found.

499 500 501 +

The language code is truncated to a maximum length to avoid potential

502 +

denial of service attacks.

503 + 500 504

lru_cache should have a maxsize to prevent from memory exhaustion attacks,

501 505

as the provided language codes are taken from the HTTP request. See also

502 506

<https://www.djangoproject.com/weblog/2007/oct/26/security-fix/>.

503 507

"""

504 508

if lang_code:

509 +

# Truncate the language code to a maximum length to avoid potential

510 +

# denial of service attacks.

511 +

if len(lang_code) > LANGUAGE_CODE_MAX_LENGTH:

512 +

if (

513 +

not strict

514 +

and (index := lang_code.rfind("-", 0, LANGUAGE_CODE_MAX_LENGTH)) > 0

515 +

):

516 +

# There is a generic variant under the maximum length accepted length.

517 +

lang_code = lang_code[:index]

518 +

else:

519 +

raise ValueError("'lang_code' exceeds the maximum accepted length")

505 520

# If 'zh-hant-tw' is not supported, try special fallback or subsequent

506 521

# language codes i.e. 'zh-hant' and 'zh'.

507 522

possible_lang_codes = [lang_code]

@@ -625,13 +640,13 @@ def parse_accept_lang_header(lang_string):

625 640

functools.lru_cache() to avoid repetitive parsing of common header values.

626 641

"""

627 642

# If the header value doesn't exceed the maximum allowed length, parse it.

628 -

if len(lang_string) <= ACCEPT_LANGUAGE_HEADER_MAX_LENGTH:

643 +

if len(lang_string) <= LANGUAGE_CODE_MAX_LENGTH:

629 644

return _parse_accept_lang_header(lang_string)

630 645 631 646

# If there is at least one comma in the value, parse up to the last comma

632 647

# before the max length, skipping any truncated parts at the end of the

633 648

# header value.

634 -

if (index := lang_string.rfind(",", 0, ACCEPT_LANGUAGE_HEADER_MAX_LENGTH)) > 0:

649 +

if (index := lang_string.rfind(",", 0, LANGUAGE_CODE_MAX_LENGTH)) > 0:

635 650

return _parse_accept_lang_header(lang_string[:index])

636 651 637 652

# Don't attempt to parse if there is only one language-range value which is

Original file line number Diff line number Diff line change

@@ -1155,6 +1155,11 @@ For a complete discussion on the usage of the following see the

1155 1155

``lang_code`` is ``'es-ar'`` and ``'es'`` is in :setting:`LANGUAGES` but

1156 1156

``'es-ar'`` isn't.

1157 1157 1158 +

``lang_code`` has a maximum accepted length of 500 characters. A

1159 +

:exc:`ValueError` is raised if ``lang_code`` exceeds this limit and

1160 +

``strict`` is ``True``, or if there is no generic variant and ``strict``

1161 +

is ``False``.

1162 + 1158 1163

If ``strict`` is ``False`` (the default), a country-specific variant may

1159 1164

be returned when neither the language code nor its generic variant is found.

1160 1165

For example, if only ``'es-co'`` is in :setting:`LANGUAGES`, that's

@@ -1163,6 +1168,11 @@ For a complete discussion on the usage of the following see the

1163 1168 1164 1169

Raises :exc:`LookupError` if nothing is found.

1165 1170 1171 +

.. versionchanged:: 4.2.14

1172 + 1173 +

In older versions, ``lang_code`` values over 500 characters were

1174 +

processed without raising a :exc:`ValueError`.

1175 + 1166 1176

.. function:: to_locale(language)

1167 1177 1168 1178

Turns a language name (en-us) into a locale name (en_US).

Original file line number Diff line number Diff line change

@@ -32,3 +32,18 @@ directory-traversal via certain inputs when calling :meth:`save()

32 32

<django.core.files.storage.Storage.save()>`.

33 33 34 34

Built-in ``Storage`` sub-classes were not affected by this vulnerability.

35 + 36 +

CVE-2024-39614: Potential denial-of-service vulnerability in ``get_supported_language_variant()``

37 +

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

38 + 39 +

:meth:`~django.utils.translation.get_supported_language_variant` was subject to

40 +

a potential denial-of-service attack when used with very long strings

41 +

containing specific characters.

42 + 43 +

To mitigate this vulnerability, the language code provided to

44 +

:meth:`~django.utils.translation.get_supported_language_variant` is now parsed

45 +

up to a maximum length of 500 characters.

46 + 47 +

When the language code is over 500 characters, a :exc:`ValueError` will now be

48 +

raised if ``strict`` is ``True``, or if there is no generic variant and

49 +

``strict`` is ``False``.

Original file line number Diff line number Diff line change

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

65 65

translation_file_changed,

66 66

watch_for_translation_changes,

67 67

)

68 +

from django.utils.translation.trans_real import LANGUAGE_CODE_MAX_LENGTH

68 69 69 70

from .forms import CompanyForm, I18nForm, SelectDateForm

70 71

from .models import Company, TestModel

@@ -1888,6 +1889,16 @@ def test_get_supported_language_variant_real(self):

1888 1889

g("xyz")

1889 1890

with self.assertRaises(LookupError):

1890 1891

g("xy-zz")

1892 +

msg = "'lang_code' exceeds the maximum accepted length"

1893 +

with self.assertRaises(LookupError):

1894 +

g("x" * LANGUAGE_CODE_MAX_LENGTH)

1895 +

with self.assertRaisesMessage(ValueError, msg):

1896 +

g("x" * (LANGUAGE_CODE_MAX_LENGTH + 1))

1897 +

# 167 * 3 = 501 which is LANGUAGE_CODE_MAX_LENGTH + 1.

1898 +

self.assertEqual(g("en-" * 167), "en")

1899 +

with self.assertRaisesMessage(ValueError, msg):

1900 +

g("en-" * 167, strict=True)

1901 +

self.assertEqual(g("en-" * 30000), "en") # catastrophic test

1891 1902 1892 1903

def test_get_supported_language_variant_null(self):

1893 1904

g = trans_null.get_supported_language_variant

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