Skip to content

Update dependency djangorestframework to v3.17.2 [SECURITY] - #228

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/pypi-djangorestframework-vulnerability
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/pypi-djangorestframework-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Aug 6, 2024 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
djangorestframework (changelog) 3.13.1 → 3.17.2 age confidence

Cross-site Scripting in djangorestframework

CVE-2024-21520 / GHSA-gw84-84pc-xp82

More information

Details

Versions of the package djangorestframework before 3.15.2 are vulnerable to Cross-site Scripting (XSS) via the break_long_headers template filter due to improper input sanitization before splitting and joining with
tags.

Severity

  • CVSS Score: 2.1 / 10 (Low)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N/E:P

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Django REST framework: Potential bypass of Django DATA_UPLOAD_MAX_MEMORY_SIZE when parsing oversized JSON and urlencoded request bodies via DRF request.data

CVE-2026-73228 / GHSA-2m8g-3cmr-wg3w

More information

Details

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-data remains 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 consume oversized request bodies despite Django's configured request-size limit.

Security Impact

This does not appear to introduce:

  • Authentication bypass
  • Authorization bypass
  • Remote code execution
  • Information disclosure
  • Integrity compromise

However, it may reduce the effectiveness of deployments relying on Django's DATA_UPLOAD_MAX_MEMORY_SIZE to limit request-body resource consumption.

Potential consequences include:

  • Additional memory allocation during JSON parsing
  • Additional CPU usage while decoding large JSON payloads
  • Increased resource consumption when handling oversized request bodies
  • Reduced effectiveness of Django's configured request-size protection for DRF endpoints using request.data

The practical impact depends on deployment configuration, including:

  • upstream request-size limits
  • reverse proxy configuration
  • authentication
  • rate limiting
  • endpoint exposure
Memory Observations

During local testing I observed successful parsing of oversized request bodies despite the configured limit.

Representative measurements showed significantly increased memory allocation while parsing large JSON and urlencoded payloads.

I intentionally did not perform destructive concurrency testing or attempt to exhaust system resources.

Scope

Confirmed affected:

  • application/json
  • application/x-www-form-urlencoded

Confirmed not affected:

  • multipart/form-data
Suggested Fix Direction

One possible approach would be for DRF to enforce Django's configured DATA_UPLOAD_MAX_MEMORY_SIZE before handing the raw request stream to parsers that fully materialize request bodies in memory.

This would preserve Django's configured request-size protection for the common request.data API without requiring broader changes to Django's documented streaming interface.

Versions Tested

Affected:

  • Django 6.0.7 + DRF 3.17.1
  • Django 6.0.7 + DRF current upstream main

I did not perform a complete historical version bisect.

Disclosure

I have not publicly disclosed this behavior.

I am submitting it privately in accordance with the project's security policy because I am unsure whether maintainers consider this part of DRF's intended security boundary.

Note:

Thank you for taking the time to review this report.

If you determine that this behavior should be addressed, I would be happy to help investigate further, develop a fix, add regression tests, and submit a patch if you'd find that helpful.

I have experience as a Python/Django software engineer, security researcher, and open-source contributor, and I'd be glad to contribute if you think that would be useful.

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Django REST framework: AdminRenderer may disclose GET-protected data when rendering invalid write requests

CVE-2026-73229 / GHSA-g47c-3xmw-q6m2

More information

Details

Summary

AdminRenderer may disclose data that would normally be protected by GET permissions when rendering a 400 Bad Request response for an invalid write request.

If a view allows POST (or another write method) but denies GET, an invalid request rendered through AdminRenderer can invoke the view's GET handler and include data from the GET representation in the generated HTML response.

This behavior appears to be specific to AdminRenderer and does not affect the normal JSON rendering path.


Details

While investigating the AdminRenderer rendering flow, I observed that invalid write requests are rendered by temporarily overriding the request method and invoking the view's GET handler:

with override_method(view, request, "GET") as request:
    response = view.get(request, *view.args, **view.kwargs)

data = response.data

This execution path differs from a normal GET request.

Under normal request processing, a GET request flows through:

APIView.dispatch()
    └── APIView.initial()
            └── APIView.check_permissions()

However, during AdminRenderer rendering, the renderer directly invokes:

view.get(...)

A view whose permission class explicitly allowed POST but denied GET still executed its GET handler while rendering an invalid POST request through AdminRenderer.

As a result, data intended to be available only through an authorized GET request was included in the generated HTML response.


Proof of Concept

Using a standard ListCreateAPIView.

Permission class:

class ProbePermission(BasePermission):
    def has_permission(self, request, view):
        return request.method == "POST"

View:

class View(ListCreateAPIView):
    renderer_classes = (AdminRenderer, JSONRenderer)
    permission_classes = (ProbePermission,)
    serializer_class = ProbeSerializer

    def get_queryset(self):
        return [
            {
                "name": "visible",
                "secret": "GET-ONLY-SECRET",
            }
        ]

Expected Behaviour

GET request
→ 403 Forbidden

Invalid POST request
→ 400 Bad Request
→ Response should contain only validation errors.
→ GET-only data should not be rendered.

Observed Behaviour

GET request
→ 403 Forbidden

Invalid POST request rendered through AdminRenderer
→ 400 Bad Request
→ HTML response contains:

GET-ONLY-SECRET

Tthe same behavior is shown using a minimal APIView implementation.

Observed results:

minimal.post_400.handler_calls =
[
    ("post", "POST"),
    ("get", "GET")
]

minimal.post_400.contains_secret = True

Generic view reproduction:

generic.direct_get.status = 403
generic.direct_get.contains_secret = False

generic.post_400.status = 400
generic.post_400.contains_secret = True

generic.post_400.permission_calls =
[
    ("GenericAdminView", "POST"),
    ...
    ("GenericAdminView", "OPTIONS")
]

generic.post_400.queryset_calls =
[
    ("GenericAdminView", "GET"),
    ...
]

These observations indicate that direct GET requests are correctly denied, while the simulated GET used during AdminRenderer rendering can still retrieve the protected representation.


Impact

This issue may result in information disclosure when all of the following conditions are met:

AdminRenderer is enabled.

The client negotiates the HTML renderer (for example using Accept: text/html).

The application permits POST (or another write method).

GET requests are denied by the configured permission class.

The invalid write request returns 400 Bad Request.

The GET representation contains information that the requester would normally not be permitted to access.

This issue does not appear to affect:

JSON rendering

Standard API responses

Successful write requests

The behavior appears limited to the HTML rendering path used by AdminRenderer.


Suggested Fix

Possible approaches include:

Perform equivalent permission checks before executing the simulated GET request.

Avoid invoking view.get() when the corresponding GET request would not be permitted.

Fall back to rendering only serializer/form validation errors instead of retrieving the GET representation.

A regression test could create a permission class that allows POST while denying GET, then verify that an invalid POST rendered with AdminRenderer does not include data from the protected GET representation.


Environment

Repository:

encode/django-rest-framework

Branch tested:

security-audit-drf

Commit tested:

cf582fb58e9e5ffcc8ed78a2cb9aaa8f4865666a

Severity

  • CVSS Score: 4.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

encode/django-rest-framework (djangorestframework)

v3.17.2

Compare Source

What's Changed

Bug fixes

Full Changelog: encode/django-rest-framework@3.17.1...3.17.2

v3.17.1

Compare Source

What's Changed

Bug fixes

Full Changelog: encode/django-rest-framework@3.17.0...3.17.1

v3.17.0

Compare Source

What's Changed

Breaking changes
Features
Bug fixes
Translations
Packaging
Other changes

New Contributors

Full Changelog: encode/django-rest-framework@3.16.1...3.17.0

v3.16.1

Compare Source

This release fixes a few bugs, clean-up some old code paths for unsupported Python versions and improve translations.

Minor changes

  • Cleanup optional backports.zoneinfo dependency and conditions on unsupported Python 3.8 and lower in #​9681. Python versions prior to 3.9 were already unsupported so this isn't considered as a breaking change.

Bug fixes

  • Fix regression in unique_together validation with SerializerMethodField in #​9712
  • Fix UniqueTogetherValidator to handle fields with source attribute in #​9688
  • Drop HTML line breaks on long headers in browsable API in #​9438

Translations

  • Add Kazakh locale support in #​9713
  • Update translations for Korean translations in #​9571
  • Update German translations in #​9676
  • Update Chinese translations in #​9675
  • Update Arabic translations-sal in #​9595
  • Update Persian translations in #​9576
  • Update Spanish translations in #​9701
  • Update Turkish Translations in #​9749
  • Fix some typos in Brazilian Portuguese translations in #​9673

Documentation

  • Removed reference to GitHub Issues and Discussions in #​9660
  • Add drf-restwind and update outdated images in browsable-api.md in #​9680
  • Updated funding page to represent current scope in #​9686
  • Fix broken Heroku JSON Schema link in #​9693
  • Update Django documentation links to use stable version in #​9698
  • Expand docs on unique constraints cause 'required=True' in #​9725
  • Revert extension back from djangorestframework-guardian2 to djangorestframework-guardian in #​9734
  • Add note to tutorial about required request in serializer context when using HyperlinkedModelSerializer in #​9732

Internal changes

  • Update GitHub Actions to use Ubuntu 24.04 for testing in #​9677
  • Update test matrix to use Django 5.2 stable version in #​9679
  • Add pyupgrade to pre-commit hooks in #​9682
  • Fix test with Django 5 when pytz is available in #​9715

New Contributors

Full Changelog: encode/django-rest-framework@3.16.0...3.16.1

v3.16.0

Compare Source

This release is considered a significant release to improve upstream support with Django and Python. Some of these may change the behaviour of existing features and pre-existing behaviour. Specifically, some fixes were added to around the support of UniqueConstraint with nullable fields which will improve built-in serializer validation.

Features

  • Add official support for Django 5.1 and its new LoginRequiredMiddleware in #​9514 and #​9657
  • Add official Django 5.2a1 support in #​9634
  • Add support for Python 3.13 in #​9527 and #​9556
  • Support Django 2.1+ test client JSON data automatically serialized in #​6511 and fix a regression in #​9615

Bug fixes

  • Fix unique together validator to respect condition's fields from UniqueConstraint in #​9360
  • Fix raising on nullable fields part of UniqueConstraint in #​9531
  • Fix unique_together validation with source in #​9482
  • Added protections to AttributeError raised within properties in #​9455
  • Fix get_template_context to handle also lists in #​9467
  • Fix "Converter is already registered" deprecation warning. in #​9512
  • Fix noisy warning and accept integers as min/max values of DecimalField in #​9515
  • Fix usages of open() in setup.py in #​9661

Translations

  • Add some missing Chinese translations in #​9505
  • Fix spelling mistakes in Farsi language were corrected in #​9521
  • Fixing and adding missing Brazilian Portuguese translations in #​9535

Removals

  • Remove support for Python 3.8 in #​9670
  • Remove long deprecated code from request wrapper in #​9441
  • Remove deprecated AutoSchema._get_reference method in #​9525

Documentation and internal changes

  • Provide tests for hashing of OperandHolder in #​9437
  • Update documentation: Add adrf third party package in #​9198
  • Update tutorials links in Community contributions docs in #​9476
  • Fix usage of deprecated Django function in example from docs in #​9509
  • Move path converter docs into a separate section in #​9524
  • Add test covering update view without queryset attribute in #​9528
  • Fix Transifex link in #​9541
  • Fix example httpie call in docs in #​9543
  • Fix example for serializer field with choices in docs in #​9563
  • Remove extra <> in validators example in #​9590
  • Update strftime link in the docs in #​9624
  • Switch to codecov GHA in #​9618
  • Add note regarding availability of the action attribute in 'Introspecting ViewSet actions' docs section in #​9633
  • Improved description of allowed throttling rates in documentation in #​9640
  • Add rest-framework-gm2m-relations package to the list of 3rd party libraries in #​9063
  • Fix a number of typos in the test suite in the docs in #​9662
  • Add django-pyoidc as a third party authentication library in #​9667

New Contributors

Full Changelog: encode/django-rest-framework@3.15.2...3.16.0

v3.15.2

Compare Source

What's Changed

New Contributors

Full Changelog: encode/django-rest-framework@3.15.1...3.15.2

v3.15.1: Version 3.15.1

Compare Source

What's Changed

New Contributors

Full Changelog: encode/django-rest-framework@3.15.0...3.15.1

v3.15.0

Compare Source

What's Changed

Released 15th March 2024

  • Django 5.0 and Python 3.12 support [#​9157]
  • Use POST method instead of GET to perform logout in browsable API [9208]
  • Added jQuery 3.7.1 support & dropped previous version [#​9094]
  • Use str as default path converter [#​9066]
  • Document support for http.HTTPMethod in the @​action decorator added in Python 3.11 [#​9067]
  • Update exceptions.md [#​9071]
  • Partial serializer should not have required fields [#​7563]
  • Propagate 'default' from model field to serializer field. [#​9030]
  • Allow to override child.run_validation call in ListSerializer [#​8035]
  • Align SearchFilter behavior to django.contrib.admin search [#​9017]
  • Class name added to unknown field error [#​9019]
  • Fix: Pagination response schemas. [#​9049]

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@vercel

vercel Bot commented Aug 6, 2024 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
elucidate-frontend ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 6, 2024 10:43am

@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from f21633e to 70dd2bc Compare August 10, 2025 14:22
@renovate renovate Bot changed the title fix(deps): update dependency djangorestframework to v3.15.2 [security] chore(deps): update dependency djangorestframework to v3.15.2 [security] Sep 25, 2025
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch 2 times, most recently from 3dbd803 to a88c27f Compare November 25, 2025 18:36
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from a88c27f to 736b5b9 Compare February 2, 2026 19:06
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from 736b5b9 to 83f5faa Compare February 12, 2026 11:36
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from 83f5faa to 2a46aac Compare March 13, 2026 13:27
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from 2a46aac to a35f906 Compare March 26, 2026 17:27
@renovate renovate Bot changed the title chore(deps): update dependency djangorestframework to v3.15.2 [security] chore(deps): update dependency djangorestframework to v3.15.2 [security] - autoclosed Mar 27, 2026
@renovate renovate Bot closed this Mar 27, 2026
@renovate
renovate Bot deleted the renovate/pypi-djangorestframework-vulnerability branch March 27, 2026 01:54
@renovate renovate Bot changed the title chore(deps): update dependency djangorestframework to v3.15.2 [security] - autoclosed chore(deps): update dependency djangorestframework to v3.15.2 [security] Mar 30, 2026
@renovate renovate Bot reopened this Mar 30, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch 2 times, most recently from a35f906 to 94d0c4f Compare March 30, 2026 17:49
@renovate renovate Bot changed the title chore(deps): update dependency djangorestframework to v3.15.2 [security] Update dependency djangorestframework to v3.15.2 [SECURITY] Apr 8, 2026
@renovate renovate Bot changed the title Update dependency djangorestframework to v3.15.2 [SECURITY] Update dependency djangorestframework to v3.15.2 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot changed the title Update dependency djangorestframework to v3.15.2 [SECURITY] - autoclosed Update dependency djangorestframework to v3.15.2 [SECURITY] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch 2 times, most recently from 94d0c4f to 49a850a Compare April 27, 2026 21:13
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from 49a850a to 3499d56 Compare July 21, 2026 01:59
@renovate
renovate Bot force-pushed the renovate/pypi-djangorestframework-vulnerability branch from 3499d56 to 1f69cb6 Compare August 11, 2026 23:12
@renovate renovate Bot changed the title Update dependency djangorestframework to v3.15.2 [SECURITY] Update dependency djangorestframework to v3.17.2 [SECURITY] Sep 1, 2026
@renovate

renovate Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: server/poetry.lock

No module named 'sre_parse'

This branch was successfully deployed

1 active (outdated) deployment
Preview — f21633e9 Deployed Aug 6, 2024 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants