Skip to content
Threat Feed
high advisory

Django REST framework: JSONParser memory exhaustion via charset parameter

Django REST framework (DRF) JSONParser fails to validate charset codecs, allowing attackers to bypass DATA_UPLOAD_MAX_MEMORY_SIZE limits through malicious compression, leading to significant memory amplification.

Triage facts

Revision 1
Applicability
Django REST framework (>= 3.6.4)
Evidence
Unknown
Severity
High
Action
Elevated
Sources
1 public source
Freshness
Revision 1Oct 29, 22:22 UTC
Source quality
A1Likely

Django REST framework (DRF) versions 3.6.4 and later contain a vulnerability in JSONParser where the Content-Type charset parameter is used to apply arbitrary codecs to the request stream. Because DRF does not verify if the requested charset is a valid text encoding, an attacker can specify byte-transform codecs like bz2_codec or zlib_codec. This results in the request body being decompressed into memory before the DATA_UPLOAD_MAX_MEMORY_SIZE check is performed, allowing for massive memory expansion.

Attack Chain

  1. Attacker crafts a highly compressed malicious JSON payload (e.g., 108 bytes).
  2. Attacker initiates a POST request to a DRF endpoint accepting JSON.
  3. Attacker sets the Content-Type header to application/json; charset=bz2_codec.
  4. Django receives the request and initializes JSONParser.
  5. JSONParser calls codecs.getreader() with the attacker-provided bz2_codec.
  6. The request stream is decompressed into memory by the codec reader.
  7. The expanded data is passed to json.load() while the original DATA_UPLOAD_MAX_MEMORY_SIZE check remains satisfied by the small wire-size of the payload.
  8. The worker process consumes significant memory, potentially causing a Denial of Service (DoS).

Impact

The vulnerability allows an amplification factor of over 400,000x, where a 108-byte request can force the allocation of ~50 MiB of memory, significantly increasing process peak RSS and facilitating memory-based DoS.

Recommendation

Patch the JSONParser to validate that the provided encoding is a supported text-based encoding. Implement the following check within rest_framework/parsers.py before invoking the codec:

import codecs
from rest_framework.exceptions import ParseError

if not codecs.lookup(encoding)._is_text_encoding:
 raise ParseError('Unsupported charset in Content-Type')

Until patches are applied, monitor for unusual Content-Type headers containing non-standard charset parameters in application access logs.


Immediate actions

Identify all services using Django REST framework and verify version

Detection Engineering 48h

Threat Hunt

Identify HTTP POST requests with Content-Type charset parameters indicative of compression codecs

T1059.003 high high confidence hunt now

Data: Web server access logs, Application request headers

Mitigations

Apply the suggested codec lookup validation check in rest_framework/parsers.py

immediate IT Operations

JSONParser charset codec amplification