CVE-2026-15307: 
Django vulnerability analysis and mitigation

Overview

CVE-2026-15307 is a server-side file-write and Server-Side Request Forgery (SSRF) vulnerability in Django's GeoDjango component, officially titled "Server-side file-write and request forgery via spatial lookups." It affects Django 5.2 before 5.2.17 and 6.0 before 6.0.8; earlier unsupported series (5.1.x, 5.0.x, 4.2.x) were not evaluated but may also be affected. The vulnerability was disclosed on August 4, 2026, and was reported by Bence Nagy, localhost-detect, and kimchunbok_. It carries a CVSS v3.1 base score of 8.8 (High) and a CVSS v4.0 base score of 8.7 (High) (Red Hat Advisory, Django Security Releases).

Technical details

The root cause is improper input validation in GeoDjango's spatial lookup processing, classified under CWE-73 (External Control of File Name or Path), CWE-918 (SSRF), and CWE-434 (Unrestricted Upload of File with Dangerous Type). When a spatial lookup is performed against a GeometryField or RasterField, the right-hand-side value is optimistically passed to the django.contrib.gis.gdal.GDALRaster constructor before being retried as a geometry. A dict or a JSON-encoded str is opened in write mode by GDAL regardless of the constructor's write=False default, allowing an attacker to write a file with arbitrary name and contents via a file-backed GDAL driver. Any other str is treated as a datasource path, enabling outbound network requests through GDAL virtual filesystem handlers (e.g., /vsicurl/). The attack surface includes the Django admin changelist, which allows staff users with only view permission to submit arbitrary spatial-field filter values via the query string (Django Commit f1949c1, Red Hat Bugzilla).

Impact

Successful exploitation allows a low-privileged staff user (view permission only) to write files with attacker-controlled names and contents to the server's filesystem, or to trigger outbound network requests as the Django process user. If a written file is placed in a location subsequently imported by the application (e.g., a Python module path), this can escalate to full remote code execution, compromising confidentiality, integrity, and availability of the affected system. The SSRF vector additionally enables internal network reconnaissance and potential access to cloud metadata services (Django Security Releases, Red Hat Bugzilla).

Exploitability

No public proof-of-concept exploit code is known to exist, and there is no evidence of in-the-wild exploitation at the time of disclosure (Feedly). The EPSS score is approximately 0.54%, indicating a low but non-negligible probability of exploitation in the near term. The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. Exploitation requires a low-privilege authenticated account (staff user with view permission), making it less trivially exploitable than unauthenticated vulnerabilities, but the potential for RCE makes it high priority for patching.

Exploitation steps

  1. Obtain staff access: Acquire or compromise a Django staff user account with at minimum view permission on any admin-registered model that contains a GeometryField or RasterField.
  2. Identify target model: Browse the Django admin changelist to identify models with spatial fields (GeometryField or RasterField) registered in the admin interface.
  3. Craft file-write payload: Construct a JSON dictionary string representing a GDAL raster configuration that specifies an attacker-chosen file path and contents. For example: {"name": "/path/to/writable/malicious.py", "driver": "GTiff", ...} encoded as a JSON string or dict.
  4. Submit via changelist filter: Append the crafted payload as a spatial-field filter in the admin changelist query string, e.g., GET /admin/app/model/?spatial_field=<payload>. The value reaches GDALRaster constructor and is opened in write mode, writing the file to disk.
  5. Trigger SSRF (alternative): Submit a string value beginning with a GDAL virtual filesystem prefix (e.g., /vsicurl/http://internal-host/) as the spatial lookup value to cause the Django process to make an outbound HTTP request.
  6. Achieve code execution: If the written file is placed in a Python-importable path (e.g., a Django app directory), trigger its import by restarting the application or exploiting an auto-reload mechanism, resulting in remote code execution as the Django process user (Django Commit f1949c1, Red Hat Bugzilla).

Indicators of compromise

  • Network: Unexpected outbound HTTP/HTTPS requests from the Django application server to external or internal hosts, particularly those matching GDAL virtual filesystem prefixes (e.g., /vsicurl/, /vsis3/, /vsigs/); unusual DNS lookups originating from the web server process.
  • Logs: Django admin access logs showing GET requests to changelist URLs with spatial field parameters containing JSON-like strings, dict representations, or VSI filesystem paths (e.g., ?point=/vsicurl/... or ?geom={"name":...}); SuspiciousOperation exceptions in Django logs (on patched systems, these indicate attempted exploitation).
  • File System: Unexpected new files written to application directories, particularly .py, .pyc, or configuration files with recent modification timestamps matching admin access times; new files in GDAL-writable locations with unusual names or contents.
  • Process: Unusual child processes spawned by the Django/Gunicorn/uWSGI process (e.g., shells, curl, wget); unexpected Python module imports logged at application startup following file creation events.

Mitigation and workarounds

Upgrade Django to version 5.2.17 or 6.0.8 immediately, as these releases block str and dict types from reaching the GDALRaster constructor in spatial lookup contexts (Django Security Releases). If immediate patching is not possible, restrict access to the Django admin changelist for models with spatial fields, and ensure that staff users with view-only permissions are limited to trusted individuals. Note that this fix is a backward-incompatible change: applications that intentionally pass str, pathlib.Path, or dict values to spatial lookups must now explicitly wrap them in GDALRaster(). Earlier unsupported series (5.1.x, 5.0.x, 4.2.x) should be evaluated separately and upgraded to a supported, patched version. For defense-in-depth, consider restricting available GDAL drivers per GDAL security guidance (Django Commit f1949c1).

Community reactions

The Django project officially disclosed the vulnerability alongside three other security fixes in its August 4, 2026 security release announcement, rating this issue as "high" severity per its security policy (Django Security Releases). Red Hat tracked the issue as high priority in its Bugzilla and security advisory systems (Red Hat Bugzilla). SUSE issued a security update (SUSE-SU-2026:3503-1) for its python-django packages. Coverage appeared across security news outlets including The Hacker News, GBHackers, CyberPress, and CyberSecurityNews, with community commentary on Mastodon (infosec.exchange) and LinkedIn highlighting the RCE potential and urging immediate patching. The Ansible project also released updated dev tools (v26.8.0) addressing the dependency.

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

Debian

Fixed

bookworm

python-django

Affected

sid

python-django: 3:5.2.17-1

Fixed

trixie

python-django

Affected

Ubuntu

Affected

bionic (esm-infra)

python-django

Affected

devel

python-django

Not Affected

focal (esm-infra)

python-django

Affected

jammy

python-django

Affected

noble

python-django

Affected

resolute

python-django

Affected

trusty (esm-infra-legacy)

python-django

Not Affected

xenial (esm-infra-legacy)

python-django

Not Affected

RHEL / CentOS

Unknown

Alpine

Fixed

edge

py3-django: 5.2.17-r0

Fixed

Source: This report was generated using AI

Related Django vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-15307HIGH8.7
  • Django logoDjango
  • authentik-2026.2
NoYesAug 04, 2026
CVE-2026-15830MEDIUM6.9
  • Django logoDjango
  • django
NoYesAug 04, 2026
CVE-2026-53877MEDIUM6.3
  • Django logoDjango
  • py3-django
NoYesJul 07, 2026
CVE-2026-53878MEDIUM5.3
  • Django logoDjango
  • python3-django5
NoYesJul 07, 2026
CVE-2026-48588LOW2.3
  • Django logoDjango
  • authentik-2026.2
NoYesJul 07, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management