Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessHold previously issued DRF authtoken
-
DeliveryOperator revokes via TokenProxy.delete()
-
ExploitDeletion silently matches zero rows
-
ExecutionToken remains valid indefinitely
-
ImpactContinue authenticating to API as victim
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A10:2025 - Mishandling of Exceptional Conditions
ASVS 5.0
V16 - Security Logging and Error Handling Error detection with action
|
| Exploitation Conditions | Exploitation requires that token revocation is performed by calling delete() on a TokenProxy instance (from applications, administrative integrations, or operational scripts) on DRF 3.12.0 through 3.18.1. Source-code test evidence indicates the silent zero-row deletion is reached on Django's deletion-collector slow path - for example when a model defines a cascading ForeignKey to Token, which pushes deletion onto the pk-matching path where the proxy's user-id pk fails to match the Token key primary key. Limiting factors: DRF's built-in TokenAdmin.delete_model is NOT affected because it maps back to the concrete Token, so sites that revoke only through the standard Django admin are safe; the attacker must already possess a previously issued token; and because DRF tokens never auto-expire, the exposure window is unbounded until manual database cleanup. |
| Impact | CVSS is 7.4 (High) with vector AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N, but the practical risk profile is that of a credential-hygiene / failed-revocation defect (CWE-390), not a direct remote exploit. No EPSS score, no CISA KEV listing, and no public POC were provided in the input, so there is no public exploit identified at time of analysis and no evidence of active or widespread exploitation - signals are consistent rather than conflicting. The High CVSS is driven by C:H/I:H (a live API token grants read/write as the token's user), while AC:H correctly reflects that the silent-deletion path is not universally hit. A key nuance: the vector reports PR:N (unauthenticated), yet the realistic actor is someone who already holds a legitimately issued token that an operator attempted to revoke - the 'attack' is continued use of a credential that revocation silently failed to remove, so the PR:N labeling is technically per-vector but should not be read as 'anonymous remote code execution.' Real priority is moderate and situational: elevated for organizations that programmatically revoke tokens via TokenProxy.delete() (custom admin integrations, SSO/offboarding scripts) and negligible for those relying only on DRF's built-in TokenAdmin, which is unaffected. |
| Exploit ScenarioDerived | After a DRF API token is known compromised or an employee is offboarded, an operational/admin script revokes it by calling delete() on a TokenProxy instance; the query matches zero rows and reports success, so the token silently remains live and continues authenticating to the API indefinitely. The attacker who retains that token keeps reading and writing API data as the victim user while administrators believe access was cut off. No public exploit code exists and exploitation is passive, relying on retention of a token that revocation failed to remove. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 21, 2026
Failed token revocation in Django REST Framework 3.12.0 through 3.18.1 leaves API credentials live after they are supposedly revoked: calling delete() on a TokenProxy instance issues a DELETE that matches no row, returns a zero count, and raises no error, so applications, admin integrations, or operational scripts that trust the return value believe the credential is gone while it continues to authenticate requests. The defect is a credential-hygiene and failed-revocation problem (CWE-390) rather than a directly exploitable remote flaw - the CVSS 3.1 base score is 7.4 (High) with vector AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N, and because DRF tokens never expire automatically, any token that escapes revocation stays valid indefinitely until the database row is cleaned up manually. No public exploit code or confirmed active exploitation (CISA KEV) was identified at time of analysis; the practical prerequisite is that an attacker already holds a previously issued token that the victim attempted to revoke through the affected code path.
RemediationAI
Upgrade djangorestframework to 3.18.2, which contains the upstream fix (commit af3fabfd517307fbc5d500fba1ab8f6e25f220b0) that re-routes TokenProxy deletion onto the concrete Token - see the advisory at https://github.com/encode/django-rest-framework/security/advisories/GHSA-xw6w-gcfp-cf8m and the release at https://github.com/encode/django-rest-framework/releases/tag/3.18.2. If upgrading immediately is not possible, rewrite every revocation path to delete via the concrete model, e.g. Token.objects.filter(key=token.key).delete() or Token.objects.filter(user=user).delete(), and treat the reference-count return of any TokenProxy.delete() call as untrustworthy. Because the silent failure means past revocations may not have taken effect, audit the authtoken_token table against your intended state and remove or regenerate any token that should already be gone - with no patch applied, tokens do not expire, so the exposure window is unbounded. Operators who monitored revocation through post_delete receivers connected to TokenProxy should also add a concrete Token receiver after upgrading, since the fixed code emits signals for Token rather than the proxy; this changes signal sender semantics and any handler keyed on the proxy will stop firing.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Django REST Framework's authtoken app defines Token, whose primary key is the token string itself (key), and TokenProxy, a Django proxy model over Token that is keyed on the owning user (its pk maps to the user id via the OneToOne relation to the user model). Django's deletion collector removes objects by pk, so deleting through the proxy compares the concrete Token table's key column against a user id, matching nothing. On the fast path Django may still resolve correctly, but the failure reliably appears on the collector's slower path - for example when another model defines a cascading ForeignKey to Token, forcing per-pk deletion - which is exactly the scenario the upstream regression tests construct. The fix in 3.18.2 adds a TokenProxyQuerySet.delete() and a TokenProxy.delete() override that re-resolve the operation onto the concrete Token (filtering on key) and clear the in-memory key, and it removes the now-redundant TokenAdmin.delete_model workaround. A side effect worth noting: the row is now deleted as the concrete Token, so post_delete receivers connected to TokenProxy will not fire, which can blind audit logging that relied on proxy-sender signals. The assigned CWE-390 (Detection of Error Condition Without Action) captures the root cause: the ORM signals a zero-row outcome but the calling code has no mechanism to detect or act on the silent no-op.
Know when Django Rest Framework gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Token reuse occurs over the network (AV:N); reaching the silent-deletion path depends on deployment/revocation specifics (AC:H); a surviving token grants full API read/write (C:H/I:H) with no availability impact (A:N).
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
Django REST framework is a toolkit for building Web APIs. From 3.12.0 until 3.18.2, TokenProxy.delete() in rest_framework/authtoken/models.py uses the proxy's user-id pk while the concrete Token token-string primary key identifies rows, so Django issues a deletion query that matches no row and reports zero deletions without raising an error. Applications, administrative integrations, or operational scripts that revoke credentials through a TokenProxy instance can therefore believe revocation succeeded while the token remains live and continues authenticating. DRF's own TokenAdmin.delete_model workaround is not affected, but other callers can leave access available indefinitely because DRF tokens do not expire automatically. This issue is fixed in version 3.18.2.
Technical POC Analysis
CWE-390 (Detection of Error Condition Without Action), also mapped to CWE-613.
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
Django REST Framework 3.12.0 through 3.18.1 can report that an API token was revoked while leaving the credential active in the database, so access intended to be removed may continue to authenticate indefinitely. This affects application teams, admin integrations, and operational scripts that rely on DRF token deletion for access control, creating an access-governance and credential-hygiene risk that leadership should treat as a control failure rather than a remote exploitation event. No public exploit identified at time of analysis, but any previously issued token that escapes revocation remains usable until the database row is manually removed.
No vendor-released patch identified at time of analysis; manually delete TokenProxy rows and verify row counts instead of trusting delete() return values, audit and rotate any token that may have escaped revocation, add monitoring/alerting for authentication with supposedly revoked tokens, and implement token expiry/rotation or a supported replacement authentication mechanism until a patched release is available.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
More in Django Rest Framework
View allUncontrolled resource consumption in Django REST Framework prior to 3.17.2 allows unauthenticated remote attackers to ex
Denial of service in Django REST Framework prior to 3.18.2 allows a remote unauthenticated client to pin synchronous wor
Memory exhaustion in Django REST framework 3.6.4 through 3.18.1 lets a remote unauthenticated client make a single small
A flaw was found in Django REST Framework versions before 3.12.0 and before 3.11.2. Rated medium severity (CVSS 6.1), th
EUVD-2026-107547
GHSA-xw6w-gcfp-cf8m
NVD
CVE.org
EPSS
Exploit-DB