See how django compares to other vendors in security performance
DjangoCRM ships with its Django SECRETKEY hardcoded directly in the committed webcrm/settings.py rather than read from an environment variable. Since this key is used for session signing, CSRF token generation, and password reset tokens, anyone who reads the public repository can forge valid session cookies (including for the superadmin account), forge CSRF tokens, and forge password reset tokens, achieving full account takeover.
An issue was discovered in Django 5.2 before 5.2.17 and 6.0 before 6.0.8. GeoDjango spatial lookups optimistically parse the right-hand-side value as a raster by passing it to the django.contrib.gis.gdal.GDALRaster constructor. Any value used in a spatial lookup against a GeometryField or RasterField reaches this constructor, including untrusted input, for example a spatial-field filter submitted through the Django admin changelist query string by a staff user with view permission. A dict, or a str holding its JSON representation, is opened in write mode regardless of the constructor's write=False default, allowing a file with an attacker-chosen name and contents to be written through a file-backed GDAL driver. Any other str is treated as a datasource, allowing an outbound network request through a GDAL virtual filesystem handler. Writing a file to a location later imported by the application can result in remote code execution. Earlier, unsupported Django series (such as 5.1.x, 5.0.x, and 4.2.x) were not evaluated and may also be affected. Django would like to thank Bence Nagy, localhost-detect, and kimchunbok for reporting this issue.
daphne before 4.2.2 did not pass maxFramePayloadSize or maxMessagePayloadSize to Autobahn's WebSocketServerFactory. Because Autobahn defaults both values to 0 (unlimited), an unauthenticated remote attacker could send arbitrarily large WebSocket messages or frames, causing excessive memory consumption and a denial of service.
An issue was discovered in Django 5.2 before 5.2.17 and 6.0 before 6.0.8. GeoDjango spatial lookups optimistically parse the right-hand-side value as a raster by passing it to the django.contrib.gis.gdal.GDALRaster constructor. Any value used in a spatial lookup against a GeometryField or RasterField reaches this constructor, including untrusted input, for example a spatial-field filter submitted through the Django admin changelist query string by a staff user with view permission. A dict, or a str holding its JSON representation, is opened in write mode regardless of the constructor's write=False default, allowing a file with an attacker-chosen name and contents to be written through a file-backed GDAL driver. Any other str is treated as a datasource, allowing an outbound network request through a GDAL virtual filesystem handler. Writing a file to a location later imported by the application can result in remote code execution. Earlier, unsupported Django series (such as 5.1.x, 5.0.x, and 4.2.x) were not evaluated and may also be affected. Django would like to thank Bence Nagy, localhost-detect, and kimchunbok for reporting this issue.
An issue was discovered in Django 5.2 before 5.2.17 and 6.0 before 6.0.8. GeoDjango's django.contrib.gis.geos.GEOSGeometry is subject to a potential denial-of-service when parsing deeply nested GEOMETRYCOLLECTION objects supplied as well-known text (WKT), well-known binary (WKB), or hex-encoded WKB, which triggers unbounded recursion and a segmentation fault in the underlying GEOS library. Spatial field lookups and the django.contrib.gis.forms.GeometryField form field are also affected. Earlier, unsupported Django series (such as 5.1.x, 5.0.x, and 4.2.x) were not evaluated and may also be affected. Django would like to thank Andrew MacPherson and kimchunbok for reporting this issue.
An issue was discovered in Django 5.2 before 5.2.17 and 6.0 before 6.0.8. django.utils.translation.checkforlanguage() is subject to a potential denial-of-service attack when given many distinct, very long language codes, which are retained as keys in an in-memory cache and consume process memory. Such codes reach the function through the django.views.i18n.setlanguage() view, which is not routed by default. The consumed memory is bounded, since request data is limited by the DATAUPLOADMAXMEMORYSIZE setting (default 2.5 MB) and the cache holds a fixed maximum number of entries. Earlier, unsupported Django series (such as 5.1.x, 5.0.x, and 4.2.x) were not evaluated and may also be affected. Django would like to thank Jaeyoung Jang for reporting this issue.
Django's admin auto-linked URLField values without validating the scheme — a stored javascript: value rendered as a live link. Fixed in 6.0.8 and 5.2.17.
Summary
A Cross-site Scripting (XSS) vulnerability exists in the {% attrs %} template tag of the slippers Django package. When a context variable containing untrusted data is passed to {% attrs %}, the value is interpolated into an HTML attribute string without escaping, allowing an attacker to break out of the attribute context and inject arbitrary HTML or JavaScript into the rendered page.
Vulnerability details
Root cause
AttrsNode is a custom Node subclass registered via register.tag(). Unlike register.simpletag(), which automatically applies conditionalescape() when autoescape is on, custom Node.render() methods receive no automatic escaping and are fully responsible for sanitising their output. attrstring() fails to do this:
python def attrstring(key: str, value: Any): if isinstance(value, bool): return key if value else "" key = key.replace("", "-") return f'{key}="{value}"' # value is not escaped
Attack scenario
Given a template that uses {% attrs %} with a user-supplied value:
django {% load slippers %} <input {% attrs type placeholder %}>
python render(request, "search.html", {"placeholder": request.GET.get("q", "")})
An attacker crafting a request with q=" onmouseover="alert(document.cookie)" x=" produces:
html <input type="text" placeholder="" onmouseover="alert(document.cookie)" x="">
Impact
Any template that passes values derived from user input, database content, or other untrusted sources to {% attrs %} is vulnerable. Successful exploitation can lead to session hijacking, credential theft, arbitrary actions on behalf of the victim, and page defacement.
Remediation
Replace the f-string in attrstring() with formathtml(), which escapes both key and value:
python from django.utils.html import formathtml
def attrstring(key: str, value: Any): if isinstance(value, bool): return key if value else "" key = key.replace("", "-") return formathtml('{}="{}"', key, value)
Until a patch is available, sanitise untrusted values before passing them to {% attrs %}, for example with django.utils.html.escape() in the view layer.
An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. django.utils.cache.hasvaryheader() in Django does not strip leading or trailing whitespace from Vary response header values before comparison, which allows remote attackers to read cached responses via requests to URLs whose responses contain whitespace-padded Vary header values. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Navid Rezazadeh for reporting this issue.
An issue was discovered in Django 5.2 before 5.2.15 and 6.0 before 6.0.6. django.middleware.cache.UpdateCacheMiddleware in Django does not match Cache-Control response directives case-insensitively, which allows remote attackers to read responses that were incorrectly cached because their Cache-Control directives used uppercase or mixed-case values. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Ahmed Badawe for reporting this issue.
An issue was discovered in 6.0 before 6.0.2, 5.2 before 5.2.11, and 4.2 before 4.2.28. Raster lookups on RasterField (only implemented on PostGIS) allows remote attackers to inject SQL via the band index parameter. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Tarek Nakkouch for reporting this issue.
An issue was discovered in 6.0 before 6.0.2, 5.2 before 5.2.11, and 4.2 before 4.2.28. .QuerySet.orderby() is subject to SQL injection in column aliases containing periods when the same alias is, using a suitably crafted dictionary, with dictionary expansion, used in FilteredRelation. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Solomon Kebede for reporting this issue.
An issue was discovered in 6.0 before 6.0.2, 5.2 before 5.2.11, and 4.2 before 4.2.28. django.utils.text.Truncator.chars() and Truncator.words() methods (with html=True) and the truncatecharshtml and truncatewordshtml template filters allow a remote attacker to cause a potential denial-of-service via crafted inputs containing a large number of unmatched HTML end tags. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Seokchan Yoon for reporting this issue.
An issue was discovered in Django 5.1 before 5.1.5, 5.0 before 5.0.11, and 4.2 before 4.2.18. Lack of upper-bound limit enforcement in strings passed when performing IPv6 validation could lead to a potential denial-of-service attack. The undocumented and private functions cleanipv6address and isvalidipv6address are vulnerable, as is the django.forms.GenericIPAddressField form field. (The django.db.models.GenericIPAddressField model field is not affected.)
An issue was discovered in Django 5.1 before 5.1.7, 5.0 before 5.0.13, and 4.2 before 4.2.20. The django.utils.text.wrap() method and wordwrap template filter are subject to a potential denial-of-service attack when used with very long strings.
An issue was discovered in 6.0 before 6.0.2, 5.2 before 5.2.11, and 4.2 before 4.2.28.
ASGIRequest allows a remote attacker to cause a potential denial-of-service via a crafted request with multiple duplicate headers. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected.
Django would like to thank Jiyong Yang for reporting this issue.
An issue was discovered in 6.0 before 6.0.2, 5.2 before 5.2.11, and 4.2 before 4.2.28. ASGIRequest allows a remote attacker to cause a potential denial-of-service via a crafted request with multiple duplicate headers. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Jiyong Yang for reporting this issue.
An issue was discovered in 6.0 before 6.0.3, 5.2 before 5.2.12, and 4.2 before 4.2.29. URLField.topython() in Django calls urllib.parse.urlsplit(), which performs NFKC normalization on Windows that is disproportionately slow for certain Unicode characters, allowing a remote attacker to cause denial of service via large URL inputs containing these characters. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Seokchan Yoon for reporting this issue.
An issue was discovered in Django 6.0 before 6.0.7 and 5.2 before 5.2.16. UpdateCacheMiddleware and the cachepage() decorator cache responses that vary on cookies when the incoming request carries unrelated cookies, which allows remote attackers to read private data from the shared cache. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Chris Whyland for reporting this issue.
An issue was discovered in Django 6.0 before 6.0.7 and 5.2 before 5.2.16. django.contrib.gis.gdal.GDALRaster over-reads its in-memory buffer when constructed from a bytes object, which can disclose adjacent memory or cause service degradation via a potential segmentation fault when the vsibuffer property is accessed. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Bence Nagy for reporting this issue.
An issue was discovered in Django 6.0 before 6.0.7 and 5.2 before 5.2.16. DomainNameValidator does not prohibit newlines in domain names (unless used via a form field, since CharField strips newlines). If an application uses values with newlines in an HTTP response, header injection can occur. Django itself is unaffected because HttpResponse prohibits newlines in HTTP headers. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Bence Nagy for reporting this issue.
Announce: https://www.djangoproject.com/weblog/2026/jul/07/security-releases/
CVE JSON Record for CVE-2026-48588: https://www.cve.org/CVERecord?id=CVE-2026-48588
CVE JSON Record for CVE-2026-53877: https://www.cve.org/CVERecord?id=CVE-2026-53877
CVE JSON Record for CVE-2026-53878: https://www.cve.org/CVERecord?id=CVE-2026-53878
In accordance with our security release policy, the Django team is issuing releases for Django 6.0.7 and Django 5.2.16. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.
CVE-2026-48588: Potential exposure of private data via cached Set-Cookie response
django.middleware.cache.UpdateCacheMiddleware and django.views.decorators.cache.cachepage avoided caching responses that set a cookie while varying on Cookie only when the incoming request contained no cookies at all. When the request already carried an unrelated cookie (such as a language or theme preference cookie), the protection did not apply, allowing a response that sets a session or other sensitive cookie to be stored in Django's shared cache.
This issue has severity "low" according to the Django security policy.
Thanks to Chris Whyland for the report.
CVE-2026-53877: Heap buffer over-read in GDALRaster
When django.contrib.gis.gdal.GDALRaster was instantiated with a bytes object representing a raster file, the vsibuffer property could over-read the allocated buffer by approximately 32 bytes. This could result in information disclosure of adjacent heap memory or, in rare cases, a segmentation fault. Only rasters stored in GDAL's virtual filesystem were affected.
This issue has severity "low" according to the Django security policy.
Thanks to Bence Nagy for the report.
CVE-2026-53878: Header injection possibility since DomainNameValidator accepted newlines in input
django.core.validators.DomainNameValidator accepted newlines in domain names. If such values were included in HTTP responses, header injection attacks were possible. Django itself wasn't vulnerable because HttpResponse prohibits newlines in HTTP headers.
The vulnerability only affected uses of DomainNameValidator outside Django form fields, as CharField strips newlines by default.
This issue has severity "low" according to the Django security policy.
Thanks to Bence Nagy for the report.
Affected supported versions
Django main Django 6.1 (currently at beta status) Django 6.0 Django 5.2
Resolution
Patches to resolve the issue have been applied to Django's main, 6.1 (currently at beta status), 6.0, and 5.2 branches. The patches may be obtained from the following changesets.
CVE-2026-48588: Potential exposure of private data via cached Set-Cookie response
On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch
CVE-2026-53877: Heap buffer over-read in GDALRaster
On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch
CVE-2026-53878: Header injection possibility since DomainNameValidator accepted newlines in input
On the main branch On the 6.1 branch On the 6.0 branch On the 5.2 branch
The following releases have been issued
Django 6.0.7 (tarball | checksums) Django 5.2.16 (tarball | checksums)
The PGP key ID used for this release is Jacob Walls: 131403F4D16D8DC7
General notes regarding security reporting
As always, we ask that potential security issues be reported via private email to security () djangoproject com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.
An issue was discovered in 6.0 before 6.0.5 and 5.2 before 5.2.14. django.middleware.cache.UpdateCacheMiddleware erroneously caches requests where the Vary header contained an asterisk (''). This can lead to private data being stored and served. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Ahmad Sadeddin for reporting this issue.
Derived classes of the django.core.files.storage.Storage base class which override generatefilename() without replicating the file path validations existing in the parent class, allow for potential directory-traversal via certain inputs when calling save(). Built-in Storage sub-classes were not affected by this vulnerability.
Affected versions =================
Django main development branch Django 5.1 Django 5.0 Django 4.2
django.utils.html.urlize() was subject to a potential denial-of-service attack via certain inputs with a very large number of brackets.
Affected versions =================
Django main development branch Django 5.1 Django 5.0 Django 4.2
The django.contrib.auth.backends.ModelBackend.authenticate() method allows remote attackers to enumerate users via a timing attack involving login requests for users with unusable passwords.
Affected versions =================
Django main development branch Django 5.1 Django 5.0 Django 4.2
An issue was discovered in 6.0 before 6.0.5 and 5.2 before 5.2.14. Response headers do not vary on cookies if a session is not modified, but SESSIONSAVEEVERYREQUEST is True. A remote attacker can steal a user's session after that user visits a cached public page. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Cantina for reporting this issue.
An issue was discovered in 6.0 before 6.0.5 and 5.2 before 5.2.14. ASGI requests with a missing or understated Content-Length header can bypass the FILEUPLOADMAXMEMORYSIZE limit, potentially loading large files into memory and causing service degradation. As a reminder, Django expects a limit to be configured at the web server level rather than solely relying on FILEUPLOADMAXMEMORYSIZE. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Kyle Agronick for reporting this issue.
Announce: https://www.djangoproject.com/weblog/2026/may/05/security-releases/
CVE JSON Record for CVE-2026-5766: https://www.cve.org/CVERecord?id=CVE-2026-5766
CVE JSON Record for CVE-2026-35192: https://www.cve.org/CVERecord?id=CVE-2026-35192
CVE JSON Record for CVE-2026-6907: https://www.cve.org/CVERecord?id=CVE-2026-6907
In accordance with our security release policy, the Django team is issuing releases for Django 6.0.5 and Django 5.2.14. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.
CVE-2026-5766: Potential denial-of-service vulnerability in ASGI requests via file upload limit bypass
ASGI requests with a missing or understated Content-Length header could bypass the FILEUPLOADMAXMEMORYSIZE limit, potentially loading large files into memory and causing service degradation.
As a reminder, Django expects a limit to be configured at the web server level rather than solely relying on FILEUPLOADMAXMEMORYSIZE.
This issue has severity "low" according to the Django security policy.
This issue was originally highlighted by Kyle Agronick in Trac. Thanks to Jacob Walls for following up and reporting it.
CVE-2026-35192: Session fixation via public cached pages and SESSIONSAVEEVERYREQUEST
Response headers did not vary on cookies if a session was not modified, but SESSIONSAVEEVERYREQUEST was True. A remote attacker could steal a user's session after that user visits a cached public page.
This issue has severity "low" according to the Django security policy.
CVE-2026-6907: Potential exposure of private data due to incorrect handling of Vary: in UpdateCacheMiddleware
Previously, django.middleware.cache.UpdateCacheMiddleware would erroneously cache requests where the Vary header contained an asterisk (''). This could lead to private data being stored and served.
This issue has severity "low" according to the Django security policy.
Thanks to Ahmad Sadeddin for the report.
Affected supported versions
Django main Django 6.0 Django 5.2
Resolution
Patches to resolve the issue have been applied to Django's main, 6.0, and 5.2 branches. The patches may be obtained from the following changesets.
CVE-2026-5766: Potential denial-of-service vulnerability in ASGI requests via file upload limit bypass
On the main branch On the 6.0 branch On the 5.2 branch
CVE-2026-35192: Session fixation via public cached pages and SESSIONSAVEEVERYREQUEST
On the main branch On the 6.0 branch On the 5.2 branch
CVE-2026-6907: Potential exposure of private data due to incorrect handling of Vary: in UpdateCacheMiddleware
On the main branch On the 6.0 branch On the 5.2 branch
The following releases have been issued
Django 6.0.5 (tarball | checksums) Django 5.2.14 (tarball | checksums)
The PGP key ID used for this release is Sarah Boyce: 3955B19851EA96EF
General notes regarding security reporting
As always, we ask that potential security issues be reported via private email to security () djangoproject com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.