☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Django logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 5.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N 🐛 CWE-918
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-87890

CVE-2026-87890 Server-Side Request Forgery in Django
📅 PUBLISHED: 2026-10-06 00:00 UTC 🔄 UPDATED: 2026-10-09 23:00 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.29%
👁️
0.29% probability
7.2× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1190
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: USA License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 5.3
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: N Privileges Required None
UI: N User Interaction None
S: U Scope Unchanged
C: L Confidentiality Low
I: N Integrity None
A: N Availability None
5.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-87890 is a Server-Side Request Forgery (SSRF) flaw in Django's spatial lookups, arising from an incomplete fix for the earlier CVE-2026-15307. An attacker who can supply bytes values to the affected lookups can force the Django process to issue network requests to attacker-chosen destinations by referencing an external raster source in a crafted VRT (GDAL Virtual Format) document. Django 6.1 before 6.1.2, 6.0 before 6.0.9, and 5.2 before 5.2.18 are affected; unsupported series (5.1.x, 5.0.x, 4.2.x) were not evaluated and may also be vulnerable. Impact is limited-confidentiality information disclosure via SSRF (CVSS 5.3), with the Django process acting as a network pivot — no public PoC, exploit code, or Nuclei template is available, and the issue is not in CISA KEV.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

The vulnerability class is CWE-918 (Server-Side Request Forgery), confirmed by the NVD description. The flaw is an incomplete fix for a prior SSRF issue, CVE-2026-15307, in Django's spatial lookups. Spatial lookups are the query components that operate on geographic/geometric fields via GeoDjango and its GDAL/GEOS backend stack.

The attack mechanism described is specific: an attacker "who can supply bytes values" can "cause the Django process to make network requests via a crafted VRT document referencing an external raster source." In GDAL, VRT (Virtual Raster) is an XML-based format that can reference external raster sources by URI/path. The vulnerability arises because a complete fix should have rejected or constrained the processing of attacker-supplied raster input so that it cannot trigger outbound fetches of external sources. The incomplete fix left a path where a bytes value (raw binary raster/VRT content supplied through a spatial lookup) is parsed and, because it contains a VRT <SourceFilename>-style external reference, causes the server to dereference that external resource over the network.

The key technical facts derivable from the description:

  • Trigger point: Django spatial lookups accepting attacker-controlled bytes.
  • Payload: a crafted VRT document embedding a reference to an external raster source.
  • Effect: the Django process itself makes the outbound network request (SSRF), not the client.
  • Relationship: this CVE is the evasion of the CVE-2026-15307 remediation — the same root cause class, incompletely closed.

Insufficient technical detail is available to name the exact lookup classes, parameters, or code paths; the NVD description does not provide them, and they must not be invented. What can be stated confidently is that any code path where attacker-supplied binary geospatial data reaches the spatial lookup / GDAL parsing layer is in scope. The CVSS vector (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N) indicates remote exploitation with no privileges or user interaction, unchanged scope, and limited confidentiality impact only — consistent with SSRF used to reach internal-only resources reachable from the Django host.

Exploitation Scenarios

No public PoC is available; the attack chain below is inferred strictly from the vulnerability class (SSRF via crafted VRT raster reference) and the NVD description. No specific function, parameter, or endpoint names are asserted because the description does not provide them.

  1. Reconnaissance / target identification. An attacker identifies a Django deployment exposing the geographic/spatial feature set (GeoDjango), where request data can reach spatial lookups that accept binary raster input. Targeted fingerprinting keys on Django version disclosure and on application endpoints that accept file/blob uploads consumed by spatial queries.

  2. Triggering the flaw class. The attacker crafts a VRT document — an XML raster virtualization file whose purpose is to reference an external raster source — and supplies its bytes to the vulnerable spatial lookup. Because the fix for CVE-2026-15307 was incomplete, the parser does not adequately restrict external source dereferencing, so the lookup processes the reference rather than rejecting it.

  3. Payload / execution method. The VRT's external raster source reference is the payload. It is not the reference itself that is dangerous; the danger is that the Django server, running with its own network position, resolves and fetches that source. The attacker selects a target: an internal-only HTTP service, a cloud metadata endpoint, a file/URL reachable solely from the server's network segment, or an external listener the attacker controls to confirm blind SSRF.

  4. Post-exploitation impact. Consistent with CVSS C:L / I:N / A:N, the primary impact is information disclosure: reading responses from internal services the attacker cannot reach directly, confirming internal network topology, or obtaining credentials/config exposed on an internal endpoint. The SSRF can also serve as a foothold for lateral reconnaissance. No integrity or availability impact is scored, and there is no evidence in the supplied data of remote code execution, so claims of arbitrary command execution would be unsupported.

Impact Assessment

Affected systems are Django deployments at versions 6.1 prior to 6.1.2, 6.0 prior to 6.0.9, and 5.2 prior to 5.2.18, specifically those that expose spatial-lookup functionality (GeoDjango) to untrusted input. Unsupported series 5.1.x, 5.0.x, and 4.2.x were not evaluated and may additionally be affected; organizations running those branches cannot assume immunity.

Blast radius is bounded by the environment's network topology, not by Django itself. Because the request originates from the Django process, any resource that process can reach — internal APIs, admin planes, cloud instance metadata, databases on an internal subnet — becomes reachable in a read-only sense. CVSS 5.3 with scope unchanged (S:U), confidentiality low (C:L), and no integrity or availability impact (I:N/A:N) defines a moderate-severity exposure. The absence of public exploit code, a Nuclei template, and CISA KEV listing lowers immediate opportunistic risk, but the flaw is a repeat of a previously exploited pattern (CVE-2026-15307) and incomplete-fix regressions are frequently rediscovered by researchers. Public-facing GeoDjango applications handling untrusted geospatial data should treat this as a priority though not emergency fix.

Detection Guidance

Sigma Rule

title: Suspicious VRT Raster External Reference via Django Spatial Lookups
id: 6f0e8a2c-3b41-4d9e-9c2a-7d5f1b8e4a10
status: experimental
description: Detects HTTP request bodies containing VRT (Virtual Raster) XML that reference an external raster source, indicative of CVE-2026-87890 SSRF exploitation against Django spatial lookups.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-87890
author: valtersit.com Threat Intelligence
date: 2026/01/01
logsource:
  category: webserver
detection:
  selection_vrt_marker:
    - 'cs-body|contains': 'VRTDataset'
    - 'cs-body|contains': 'SourceFilename'
  selection_uri_scheme:
    - 'cs-body|contains': 'http://'
    - 'cs-body|contains': 'https://'
    - 'cs-body|contains': 'file://'
  selection_external_ref:
    - 'cs-body|contains': 'relativeToVRT'
  condition: selection_vrt_marker and selection_uri_scheme
fields:
  - clientip
  - cs-method
  - cs-uri-stem
  - cs-body
falsepositives:
  - Legitimate geospatial upload workflows that intentionally reference external raster sources
level: medium
tags:
  - attack.t1190
  - cwe.918

YARA Rule

rule CVE_2026_87890_VRT_SSRF
{
    meta:
        description = "Detects crafted VRT raster documents embedding external raster source references used to trigger SSRF in Django spatial lookups (CVE-2026-87890)"
        author = "valtersit.com Threat Intelligence"
        date = "2026-01-01"
        reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-87890"
        cwe = "CWE-918"

    strings:
        $vrt_root  = "VRTDataset" ascii wide nocase
        $src_file  = "SourceFilename" ascii wide nocase
        $rel_vrt   = "relativeToVRT" ascii wide nocase
        $http      = "http://" ascii
        $https     = "https://" ascii
        $fileuri   = "file://" ascii
        $meta_aws  = "169.254.169.254" ascii
        $band      = "VRTRasterBand" ascii wide nocase

    condition:
        $vrt_root and $band and $src_file and $rel_vrt and
        ( any of ($http, $https, $fileuri) or $meta_aws )
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-87890 Django Spatial Lookup VRT SSRF Attempt"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"VRTDataset"; content:"SourceFilename"; content:"relativeToVRT"; pcre:"/(http|https|file):\/\//Ri"; reference:cve,2026-87890; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-87890; classtype:attempted-recon; sid:202687890; rev:1; metadata:created_at 2026_01_01, updated_at 2026_01_01, mitre_tactic_id T1190, mitre_tactic_name Exploit_Public-Facing_Application;)

Elastic Detection

sequence by host.name
  [ network where http.request.method == "POST" and
      http.request.body.content : "VRTDataset" and
      http.request.body.content : "SourceFilename" ]
  [ network where http.response.status_code >= 200 and
      http.response.status_code < 300 and
      http.request.body.content : ("http://" or "https://" or "file://") ]

Splunk SPL Query

index=web OR index=proxy
(sourcetype=access_combined OR sourcetype=stream:http)
"VRTDataset" ("SourceFilename" OR "relativeToVRT")
| rex field=_raw "(?<external_ref>(https?|file)://[^\s\"<>]+)"
| eval cve="CVE-2026-87890"
| stats count min(_time) as first_seen max(_time) as last_seen
        values(external_ref) as external_targets
        values(clientip) as source_ips by cve host
| where count > 0
| convert ctime(first_seen) ctime(last_seen)

Wazuh OSSEC Rule

<group name="web,django,cve-2026-87890,">
  <rule id="2026878" level="10">
    <if_sid>31100,31101,31108</if_sid>
    <match>VRTDataset</match>
    <match>SourceFilename</match>
    <match>relativeToVRT</match>
    <description>CVE-2026-87890: Possible Django spatial lookup SSRF via crafted VRT raster document referencing an external source.</description>
    <mitre>
      <id>T1190</id>
    </mitre>
    <group>cwe_918,ssrf,</group>
  </rule>

  <rule id="2026879" level="12">
    <if_sid>2026878</if_sid>
    <regex>(https?|file)://</regex>
    <description>CVE-2026-87890: VRT document contains external URI reference - probable SSRF exploitation attempt.</description>
    <mitre>
      <id>T1190</id>
    </mitre>
  </rule>
</group>

Mitigation & Patch Guidance

Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).

  1. Immediate mitigations.

    • Treat all attacker-supplied binary raster/geospatial input as untrusted. Where feasible, disallow user-controlled bytes from reaching spatial lookup paths that trigger GDAL VRT parsing.
    • Apply network egress controls on the Django host: block outbound requests from the application tier to internal-only ranges, link-local/cloud metadata addresses, and non-allowlisted external hosts. This directly blunts the SSRF effect even with the flaw present.
    • Place GeoDjango processing behind an isolated worker/segment with a restrictive egress policy, so a successful VRT dereference cannot pivot into sensitive internal networks.
    • Monitor for the VRT indicators in the detection rules above and alert on any application-tier request to cloud metadata or non-allowlisted internal endpoints.
  2. Patch / upgrade steps.

    • The NVD description states the issue is fixed in Django 6.1.2, 6.0.9, and 5.2.18. Upgrade to the nearest fixed release on your supported branch: 6.1.x -> 6.1.2+, 6.0.x -> 6.0.9+, 5.2.x -> 5.2.18+.
    • For unsupported branches (5.1.x, 5.0.x, 4.2.x), there is no evaluated fix; plan migration to a supported, fixed branch.
    • Because this is an incomplete-fix regression for CVE-2026-15307, verify that any earlier mitigations applied for that CVE are superseded by the newer release rather than relied upon. Obtain patch confirmation from the official Django release notes/advisory before closing remediation.
  3. Long-term hardening.

    • Institute an egress allowlist by default for application servers, with explicit exceptions reviewed regularly — SSRF classes recur and egress control is the durable control.
    • Require SSRF-safe outbound fetching patterns for any component that dereferences user-supplied URIs or formats that embed them (VRT, other GDAL virtual formats).
    • Maintain an asset inventory of GeoDjango/spatial-feature-enabled applications so regressions in spatial lookups are rapidly scoped.
    • Track the CVE-2026-15307 -> CVE-2026-87890 lineage and audit for sibling incomplete fixes in the same code area.
    • Enable dependency/version alerting for Django security releases so fixed versions are adopted promptly.

References

No public PoC, exploit code, or Nuclei template was identified in the supplied data. No threat actor campaign or in-the-wild exploitation evidence is associated with this CVE in the available data; the issue was credited to researcher "sicksec" per the NVD description.

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

product:"Django"
title:"Django"
product:"Django" "6.1"
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-87890/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.