CVE-2026-73228
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.3
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
CVE-2026-73228- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-56887
5.3
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
EUVD-2026-56887- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2m8g-3cmr-wg3w
5.3
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Summary
While investigating Django REST Framework's request parsing behavior, I identified that DRF's high-level request.data parsing appears to bypass Django's configured DATA_UPLOAD_MAX_MEMORY_SIZE protection for application/json and application/x-www-form-urlencoded request bodies.
In the tested configurations, Django correctly raises RequestDataTooBig when applications access request.body or Django's native request.POST, but DRF successfully parses the same oversized payloads through request.data.
This behavior appears to occur because DRF passes the underlying HttpRequest object directly to parsers, which consume the request stream through Django's lower-level streaming interface rather than the guarded request.body path.
I am reporting this privately because I am unsure whether this behavior is considered part of DRF's intended security boundary, but it appears to bypass a documented Django request-size protection for common DRF request parsing paths and may have availability implications.
What I Verified
I verified the behavior locally using the following combinations:
- Django 6.0.7 + DRF 3.17.1 → Affected
- Django 6.0.7 + DRF current upstream main → Affected
For both versions, the observed behavior was:
Django request.body
→ RequestDataTooBig
Django request.POST (application/x-www-form-urlencoded)
→ RequestDataTooBig
Django request.read()
→ Reads the entire oversized request body
DRF request.data
→ Successfully parses oversized JSON and urlencoded request bodies
I also confirmed that:
multipart/form-dataremains protected because DRF delegates multipart parsing to Django's multipart parser.- The behavior reproduces on both direct WSGI and ASGI servers without a reverse proxy or external request-size middleware.
Technical Details
The relevant execution flow is:
APIView
↓
rest_framework.request.Request
↓
request.data
↓
Request._load_data_and_files()
↓
Request._parse()
↓
Request._load_stream()
↓
self._stream = self._request
↓
JSONParser.parse(...)
or
FormParser.parse(...)
↓
stream.read() / json.load(...)
The important implementation detail is that DRF assigns the original Django HttpRequest object as the parser stream.
Unlike request.body and Django's native form parsing, consuming the stream through HttpRequest.read() does not trigger Django's RequestDataTooBig protection.
As a result, DRF's built-in parsers successfully consume oversized request bodies that Django itself would reject through its higher-level request interfaces.
Reproduction Steps
Environment
Python 3.13
Django 6.0.7
Django REST Framework 3.17.1 (also reproduced on current upstream main)
Configure:
DATA_UPLOAD_MAX_MEMORY_SIZE = 10
Create a simple DRF API view:
from rest_framework.views import APIView
from rest_framework.response import Response
class DemoView(APIView):
def post(self, request):
return Response(request.data)
Start the application.
Send an oversized JSON request:
POST /demo
Content-Type: application/json
Content-Length: >10 bytes
Example:
{
"value": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
}
Observed:
HTTP 200
JSON successfully parsed
Now compare against:
request.body
Observed:
RequestDataTooBig
Likewise, compare against:
request.POST
using
application/x-www-form-urlencoded
Observed:
RequestDataTooBig
This demonstrates different enforcement depending on which request API is used.
Root Cause
Django documents HttpRequest.read() as a streaming interface.
DRF exposes request.data as the primary high-level request parsing API.
Currently, DRF forwards the raw Django request stream directly to parsers before any request-size validation equivalent to Django's request.body path occurs.
Consequently:
- JSONParser
- FormParser
fully…
- Record
GHSA-2m8g-3cmr-wg3w- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-770
- Updated
- 2026-11-02
NVD
5.3
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
CVE-2026-73228- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-770
- Updated
- 2026-11-02
OSV
5.3
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
CVE-2026-73228- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-770
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-73228
5.3
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
DEBIAN-CVE-2026-73228- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-2m8g-3cmr-wg3w
5.3
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Summary
While investigating Django REST Framework's request parsing behavior, I identified that DRF's high-level request.data parsing appears to bypass Django's configured DATA_UPLOAD_MAX_MEMORY_SIZE protection for application/json and application/x-www-form-urlencoded request bodies.
In the tested configurations, Django correctly raises RequestDataTooBig when applications access request.body or Django's native request.POST, but DRF successfully parses the same oversized payloads through request.data.
This behavior appears to occur because DRF passes the underlying HttpRequest object directly to parsers, which consume the request stream through Django's lower-level streaming interface rather than the guarded request.body path.
I am reporting this privately because I am unsure whether this behavior is considered part of DRF's intended security boundary, but it appears to bypass a documented Django request-size protection for common DRF request parsing paths and may have availability implications.
What I Verified
I verified the behavior locally using the following combinations:
- Django 6.0.7 + DRF 3.17.1 → Affected
- Django 6.0.7 + DRF current upstream main → Affected
For both versions, the observed behavior was:
Django request.body
→ RequestDataTooBig
Django request.POST (application/x-www-form-urlencoded)
→ RequestDataTooBig
Django request.read()
→ Reads the entire oversized request body
DRF request.data
→ Successfully parses oversized JSON and urlencoded request bodies
I also confirmed that:
multipart/form-dataremains protected because DRF delegates multipart parsing to Django's multipart parser.- The behavior reproduces on both direct WSGI and ASGI servers without a reverse proxy or external request-size middleware.
Technical Details
The relevant execution flow is:
APIView
↓
rest_framework.request.Request
↓
request.data
↓
Request._load_data_and_files()
↓
Request._parse()
↓
Request._load_stream()
↓
self._stream = self._request
↓
JSONParser.parse(...)
or
FormParser.parse(...)
↓
stream.read() / json.load(...)
The important implementation detail is that DRF assigns the original Django HttpRequest object as the parser stream.
Unlike request.body and Django's native form parsing, consuming the stream through HttpRequest.read() does not trigger Django's RequestDataTooBig protection.
As a result, DRF's built-in parsers successfully consume oversized request bodies that Django itself would reject through its higher-level request interfaces.
Reproduction Steps
Environment
Python 3.13
Django 6.0.7
Django REST Framework 3.17.1 (also reproduced on current upstream main)
Configure:
DATA_UPLOAD_MAX_MEMORY_SIZE = 10
Create a simple DRF API view:
from rest_framework.views import APIView
from rest_framework.response import Response
class DemoView(APIView):
def post(self, request):
return Response(request.data)
Start the application.
Send an oversized JSON request:
POST /demo
Content-Type: application/json
Content-Length: >10 bytes
Example:
{
"value": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
}
Observed:
HTTP 200
JSON successfully parsed
Now compare against:
request.body
Observed:
RequestDataTooBig
Likewise, compare against:
request.POST
using
application/x-www-form-urlencoded
Observed:
RequestDataTooBig
This demonstrates different enforcement depending on which request API is used.
Root Cause
Django documents HttpRequest.read() as a streaming interface.
DRF exposes request.data as the primary high-level request parsing API.
Currently, DRF forwards the raw Django request stream directly to parsers before any request-size validation equivalent to Django's request.body path occurs.
Consequently:
- JSONParser
- FormParser
fully…
- Record
GHSA-2m8g-3cmr-wg3w- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-770
- Updated
- 2026-11-02
OSVPYSEC-2026-3827
5.3
Django REST framework: Potential bypass of Django `DATA_UPLOAD_MAX_MEMORY_SIZE` when parsing oversized JSON and urlencoded request bodies via DRF `request.data`
Summary
While investigating Django REST Framework's request parsing behavior, I identified that DRF's high-level request.data parsing appears to bypass Django's configured DATA_UPLOAD_MAX_MEMORY_SIZE protection for application/json and application/x-www-form-urlencoded request bodies.
In the tested configurations, Django correctly raises RequestDataTooBig when applications access request.body or Django's native request.POST, but DRF successfully parses the same oversized payloads through request.data.
This behavior appears to occur because DRF passes the underlying HttpRequest object directly to parsers, which consume the request stream through Django's lower-level streaming interface rather than the guarded request.body path.
I am reporting this privately because I am unsure whether this behavior is considered part of DRF's intended security boundary, but it appears to bypass a documented Django request-size protection for common DRF request parsing paths and may have availability implications.
What I Verified
I verified the behavior locally using the following combinations:
- Django 6.0.7 + DRF 3.17.1 → Affected
- Django 6.0.7 + DRF current upstream main → Affected
For both versions, the observed behavior was:
Django request.body
→ RequestDataTooBig
Django request.POST (application/x-www-form-urlencoded)
→ RequestDataTooBig
Django request.read()
→ Reads the entire oversized request body
DRF request.data
→ Successfully parses oversized JSON and urlencoded request bodies
I also confirmed that:
multipart/form-dataremains protected because DRF delegates multipart parsing to Django's multipart parser.- The behavior reproduces on both direct WSGI and ASGI servers without a reverse proxy or external request-size middleware.
Technical Details
The relevant execution flow is:
APIView
↓
rest_framework.request.Request
↓
request.data
↓
Request._load_data_and_files()
↓
Request._parse()
↓
Request._load_stream()
↓
self._stream = self._request
↓
JSONParser.parse(...)
or
FormParser.parse(...)
↓
stream.read() / json.load(...)
The important implementation detail is that DRF assigns the original Django HttpRequest object as the parser stream.
Unlike request.body and Django's native form parsing, consuming the stream through HttpRequest.read() does not trigger Django's RequestDataTooBig protection.
As a result, DRF's built-in parsers successfully consume oversized request bodies that Django itself would reject through its higher-level request interfaces.
Reproduction Steps
Environment
Python 3.13
Django 6.0.7
Django REST Framework 3.17.1 (also reproduced on current upstream main)
Configure:
DATA_UPLOAD_MAX_MEMORY_SIZE = 10
Create a simple DRF API view:
from rest_framework.views import APIView
from rest_framework.response import Response
class DemoView(APIView):
def post(self, request):
return Response(request.data)
Start the application.
Send an oversized JSON request:
POST /demo
Content-Type: application/json
Content-Length: >10 bytes
Example:
{
"value": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
}
Observed:
HTTP 200
JSON successfully parsed
Now compare against:
request.body
Observed:
RequestDataTooBig
Likewise, compare against:
request.POST
using
application/x-www-form-urlencoded
Observed:
RequestDataTooBig
This demonstrates different enforcement depending on which request API is used.
Root Cause
Django documents HttpRequest.read() as a streaming interface.
DRF exposes request.data as the primary high-level request parsing API.
Currently, DRF forwards the raw Django request stream directly to parsers before any request-size validation equivalent to Django's request.body path occurs.
Consequently:
- JSONParser
- FormParser
fully…
- Record
PYSEC-2026-3827- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-73228
5.3
Django REST framework is a toolkit for building Web APIs. Prior to 3.17.2, Django REST Framework's request.data parsing in rest_framework/request.py Request._parse() passes the underlying HttpRequest stream to JSONParser and FormParser for application/json and application/x-www-form-urlencoded bodies, bypassing Django's DATA_UPLOAD_MAX_MEMORY_SIZE protection and allowing oversized request bodies to consume additional memory and CPU. This issue is fixed in version 3.17.2.
- Record
UBUNTU-CVE-2026-73228- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:11625-1 No score
python313-djangorestframework-3.18.0-2.1 on GA media
These are all security issues fixed in the python313-djangorestframework-3.18.0-2.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:11625-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
djangorestframeworkPyPI |
before 3.17.2 | 3.17.2 |
djangorestframeworkDebian:12 |
All versions, plus listed versions 3.14.0-23.14.0-2+deb12u13.15.1-13.15.1-23.15.2-1 Show 9 moreShow less3.15.2-23.16.0-13.16.1-13.16.1-33.16.1-43.17.1+ds1-13.17.1-13.18.1+ds1-13.18.3+ds1-1 |
None known |
djangorestframeworkDebian:13 |
All versions, plus listed versions 3.16.0-13.16.1-13.16.1-33.16.1-43.17.1+ds1-13.17.1-13.18.1+ds1-13.18.3+ds1-1 |
None known |
djangorestframeworkDebian:14 |
before 3.18.1+ds1-1, plus listed versions 3.16.0-13.16.1-13.16.1-33.16.1-43.17.1+ds1-13.17.1-1 |
3.18.1+ds1-1 |
djangorestframeworkPyPI |
before 3.17.2, plus listed versions 0.10.1.10.2.00.2.10.2.2 Show 45 moreShow less0.2.30.2.40.3.00.3.10.3.20.3.30.4.02.0.02.0.12.0.22.1.02.1.12.1.102.1.112.1.122.1.132.1.142.1.152.1.162.1.172.1.22.1.32.1.42.1.52.1.62.1.72.1.82.1.92.2.02.2.12.2.22.2.32.2.42.2.52.2.62.2.72.3.02.3.12.3.102.3.112.3.122.3.132.3.142.3.22.3.3 |
3.17.2 |
djangorestframeworkUbuntu:16.04:LTS |
All versions, plus listed versions 2.4.3-23.3.1-13.3.2-13.3.2-2 |
None known |
djangorestframeworkUbuntu:18.04:LTS |
All versions, plus listed versions 3.4.0-23.7.7-1 |
None known |
djangorestframeworkUbuntu:20.04:LTS |
All versions, plus listed versions 3.9.0-23.10.2-1 |
None known |
djangorestframeworkUbuntu:22.04:LTS |
All versions, plus listed versions 3.12.1-13.12.4-13.12.4-23.12.4-2ubuntu13.12.4-2.1ubuntu1 |
None known |
djangorestframeworkUbuntu:24.04:LTS |
All versions, plus listed versions 3.14.0-2 |
None known |
djangorestframeworkUbuntu:26.10 |
All versions, plus listed versions 3.16.1-33.16.1-43.17.1+ds1-1 |
None known |
djangorestframeworkUbuntu:26.04:LTS |
All versions, plus listed versions 3.16.1-13.16.1-3 |
None known |
python-djangorestframeworkopenSUSE:Tumbleweed |
before 3.18.0-2.1 | 3.18.0-2.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-73228 is a medium vulnerability (CVSS 5.3) in Encode Django-rest-framework, published August 11, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.56%, the 46th percentile. Fixed in djangorestframework 3.17.2.
References
github.com/encode/django-rest-framework/security/advisories/GHSA-2m8g-3cmr-wg3w
github.com/encode/django-rest-framework/pull/10013
github.com/encode/django-rest-framework/commit/2912dc98042f78e27636551fc22eeaf10f725fdd
github.com/encode/django-rest-framework/commit/82ef7b7e4e0a73ba5c489b465fae7e76d948da4e
nvd.nist.gov/vuln/detail/CVE-2026-73228
github.com/encode/django-rest-framework/releases/tag/3.17.2
Show 8 moreShow less
github.com/advisories/GHSA-2m8g-3cmr-wg3w
github.com/CVEProject/cvelistV5/tree/main/cves/2026/73xxx/CVE-2026-73228.json
security-tracker.debian.org/tracker/CVE-2026-73228
github.com/encode/django-rest-framework
pypi.org/project/djangorestframework
ubuntu.com/security/CVE-2026-73228
cve.org/CVERecord?id=CVE-2026-73228
suse.com/security/cve/CVE-2026-73228
Left out here: 91 versions and the rest of 3 source descriptions. The JSON record has them.