Django 6.1.3 release notes#
November 3, 2026
Django 6.1.3 fixes five security issues with severity “low”, one security issue with severity “moderate”, and several bugs in 6.1.2. It also adds compatibility with Python 3.15.
CVE-2026-108147: Potential memory exhaustion in MultiPartParser via base64-encoded file upload#
When using django.http.multipartparser.MultiPartParser, multipart uploads
with Content-Transfer-Encoding: base64 could be buffered entirely in
memory, regardless of FILE_UPLOAD_MAX_MEMORY_SIZE, before being
passed to upload handlers, potentially consuming excessive memory.
This issue has severity “low” according to the Django security policy.
CVE-2026-111211: Potential log injection via unescaped geometry form values#
GeometryField and its widgets logged invalid
submitted values directly, allowing control characters (e.g. newlines or ANSI
escape sequences) to be written unescaped into logs. This could enable log
injection or forgery, letting attackers manipulate log appearance or
structure, especially in logs processed by external systems or viewed in
terminals.
This issue has severity “low” according to the Django security policy.
CVE-2026-111362: Server-side request forgery via crs member of GeoJSON geometries#
Earlier versions of the GeoJSON spec allowed specifying a coordinate reference system (CRS) by URL. Since GDAL still resolves these URLs, any validation, save, or query path where a geometry is instantiated from user input allowed an attacker to submit a malicious CRS that would make a network request as the Django process user, or read a file, or both.
Lookups against spatial fields, the
GeometryField form field, and
GEOSGeometry now reject GeoJSON geometries
with CRS references to external resources. The
DataSource and
LayerMapping utilities for loading trusted
data continue to accept these values.
This issue has severity “moderate” according to the Django security policy.
CVE-2026-113593: Potential exposure of private data via empty and missing Vary headers#
UpdateCacheMiddleware and
cache_page() generated the same cache key
for a request that omitted a header listed in the response’s Vary header
and a request that sent that header with an empty value. As a result, a
response cached for one of these requests could be served to the other, which
could lead to the exposure of private data.
Cache keys now distinguish between absent and empty header values, as required by RFC 9111 Section 4.1.
Responses previously cached for requests that omitted a header listed in
Vary will no longer be matched, and will be cached again on the next
request.
This issue has severity “low” according to the Django security policy.
CVE-2026-113733: Password hash disclosure to “view only” admin users with custom user models#
Admin users with the view (but not change) permission to a user model were
displayed the entire password hash when the model was not
AUTH_USER_MODEL, or when AUTH_USER_MODEL inherited its
password field from a concrete parent model through multi-table
inheritance.
This issue has severity “low” according to the Django security policy.
CVE-2026-114582: Server-side request forgery via SpatialReference string input#
SpatialReference passed string input to GDAL,
which by default resolves URLs and reads files. This behavior was not
documented by Django. Other affected methods included
GEOSGeometry.transform(),
OGRGeometry.transform(),
GDALRaster.transform(),
the srs setter of
OGRGeometry, and the
srs and
srid setters of
GDALRaster. A URL or file path reaching any
of these would issue an outbound request or read a file as the Django process
user. The attack vectors could be combined to reveal local file contents by
observing outbound requests.
SpatialReference now disables network and file access when parsing string
input on GDAL 3.9 and later. As a consequence, file paths and URLs are no
longer accepted as SpatialReference inputs. Dictionary references using the
DICT: prefix, including those prefixed with ESRI::, are rejected on all
GDAL versions.
Full protection requires GDAL 3.9 or later. Integer SRIDs are looked up
directly in the EPSG database, so prefer them when the input is untrusted. Or,
if strings must be used on lower GDAL versions, compare to an allow list. The
new gis.W001 system check warns when the installed version of GDAL is not
at least 3.9.
This issue has severity “low” according to the Django security policy.
Bugfixes#
Fixed a bug in Django 6.1 where accessing a deferred field with the
FETCH_PEERSfetch mode overwrote values that peer instances had already modified locally or loaded viarefresh_from_db()with an explicitfieldsargument. The fix also addresses aKeyErrorwhen a peer’s row had been deleted (#37436).Fixed a regression in Django 6.1 where the YAML serializer crashed if passed the
sort_keysoption (#37405).Fixed a regression in Django 6.1 where a
Valueexpression with aNonevalue and an output field other thanJSONFieldcrashed on SQLite when used in a top-levelJSONFieldinlookup (#37403). Using such an expression in anINlookup is likely unintended, since SQLNULLcannot match any value.Fixed a regression in Django 6.1 where
legend_tag()with a customattrscould add therequired_css_classmore than once (#37463).Added compatibility for
oracledb26.0.0+ (#37411).Fixed a crash in
makemessageson Windows when processing files with non-ASCII names on Python 3.15+, or with UTF-8 mode enabled on older Python versions (#37447).