티스토리 수익 글 보기

티스토리 수익 글 보기

[5.2.x] Fixed CVE-2026-53878 — Prevented newlines from being accepte… · django/django@d5d60ed · GitHub
Skip to content

Commit d5d60ed

Browse files
nessitajacobtylerwalls
authored andcommitted
[5.2.x] Fixed CVE-2026-53878 — Prevented newlines from being accepted in DomainNameValidator.
Thanks Bence Nagy for the report, and Jake Howard for reviews. Backport of 3a720d0 from main.
1 parent 6c66eb8 commit d5d60ed

3 files changed

Lines changed: 32 additions & 14 deletions

File tree

django/core/validators.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,20 @@ class DomainNameValidator(RegexValidator):
9999
def __init__(self, **kwargs):
100100
self.accept_idna = kwargs.pop("accept_idna", True)
101101

102-
if self.accept_idna:
103-
self.regex = _lazy_re_compile(
104-
r"^" + self.hostname_re + self.domain_re + self.tld_re + r"$",
105-
re.IGNORECASE,
106-
)
107-
else:
108-
self.regex = _lazy_re_compile(
109-
r"^"
110-
+ self.ascii_only_hostname_re
111-
+ self.ascii_only_domain_re
112-
+ self.ascii_only_tld_re
113-
+ r"$",
114-
re.IGNORECASE,
115-
)
102+
regex_parts = [
103+
"^",
104+
*(
105+
(self.hostname_re, self.domain_re, self.tld_re)
106+
if self.accept_idna
107+
else (
108+
self.ascii_only_hostname_re,
109+
self.ascii_only_domain_re,
110+
self.ascii_only_tld_re,
111+
)
112+
),
113+
r"\Z",
114+
]
115+
self.regex = _lazy_re_compile("".join(regex_parts), re.IGNORECASE)
116116
super().__init__(**kwargs)
117117

118118
def __call__(self, value):

docs/releases/5.2.16.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,17 @@ affected.
3333

3434
This issue has severity "low" according to the :ref:`Django security policy
3535
<severity-levels>`.
36+
37+
CVE-2026-53878: Header injection possibility since ``DomainNameValidator`` accepted newlines in input
38+
=====================================================================================================
39+
40+
:class:`~django.core.validators.DomainNameValidator` accepted newlines in
41+
domain names. If such values were included in HTTP responses, header injection
42+
attacks were possible. Django itself wasn't vulnerable because
43+
:class:`~django.http.HttpResponse` prohibits newlines in HTTP headers.
44+
45+
The vulnerability only affected uses of ``DomainNameValidator`` outside Django
46+
form fields, as ``CharField`` strips newlines by default.
47+
48+
This issue has severity "low" according to the :ref:`Django security policy
49+
<severity-levels>`.

tests/validators/tests.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,8 @@
665665
(validate_domain_name, "dashinpunytld.xn---c", None),
666666
(validate_domain_name, "python..org", ValidationError),
667667
(validate_domain_name, "python-.org", ValidationError),
668+
(validate_domain_name, "example.com\n", ValidationError),
669+
(validate_domain_name, "example.com\r\n", ValidationError),
668670
(validate_domain_name, "too-long-name." * 20 + "com", ValidationError),
669671
(validate_domain_name, "stupid-name试", ValidationError),
670672
(validate_domain_name, "255.0.0.0", ValidationError),
@@ -677,6 +679,8 @@
677679
ValidationError,
678680
),
679681
(DomainNameValidator(accept_idna=False), "ıçğü.com", ValidationError),
682+
(DomainNameValidator(accept_idna=False), "example.com\n", ValidationError),
683+
(DomainNameValidator(accept_idna=False), "example.com\r\n", ValidationError),
680684
(DomainNameValidator(accept_idna=False), "not-domain-name", ValidationError),
681685
(
682686
DomainNameValidator(accept_idna=False),

0 commit comments

Comments
 (0)