Skip to content

[FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors#2098

Open
chandrasekharan-zipstack wants to merge 1 commit into
mainfrom
fix/revert-drf-bump
Open

[FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors#2098
chandrasekharan-zipstack wants to merge 1 commit into
mainfrom
fix/revert-drf-bump

Conversation

@chandrasekharan-zipstack

Copy link
Copy Markdown
Contributor

What

Pins djangorestframework back to 3.14.0 (from 3.15.2, bumped in #2087). Reverts only the DRF entry; other batched bumps from #2087 are untouched. Touches both pyproject.toml + both uv.lock (root + backend). uv lock --check passes.

Why

DRF 3.15.2 regressed rc.343. DRF 3.15 auto-derives multi-field UniqueTogetherValidators from model UniqueConstraints (3.14 only did this for legacy unique_together). Every ModelSerializer(fields="__all__") over a model using Meta.constraints=[UniqueConstraint(...)] breaks two ways:

  1. Server-set constraint field (e.g. organization) → <field>: This field is required on create. Partially patched by [FIX] Mark server-managed organization field non-editable (DRF 3.15 compat) #2092 (5 org-attached models + mixin).
  2. Client-supplied constraint fields (TableSettings, ProfileManager, agentic table settings, lookups) → non_field_errors: "...must make a unique set" raised at is_valid(), short-circuiting the views' intended except IntegrityError: raise DuplicateData(<friendly>) path. This replaced the friendly message and moved the error from a top-level detail string into nested non_field_errors, which the frontend doesn't surface → silent failures.

QA-reported symptoms traced to this (rc.343)

  • Prompt table settings not editable after first save (re-save → 400, update_or_create never runs).
  • Duplicate LLM profile name → no error notification (silent fail); spec test_profile_manager_dependency: Expected duplicate-profile error, got "".

Trade-off

Loses the CVE-2024-21520 XSS patch carried by 3.15.2 — intentionally deprioritized for now. The 3.15 upgrade will be reattempted as its own PR with a serializer-level fix (drop auto-derived uniqueness validators so duplicates flow to the DB IntegrityError → DuplicateData path).

Note on recent fixes

The organization editable=False changes (#2092) remain correct under 3.14 — org is set server-side in save() from UserContext, never from request input, and the migrations are state-only (no DDL). No rollback needed there.

🤖 Generated with Claude Code

The DRF 3.15.2 bump (#2087) regressed rc.343. DRF 3.15 auto-derives
multi-field UniqueTogetherValidators from model UniqueConstraints, which
3.14 only did for legacy unique_together. Two breakages followed for every
ModelSerializer(fields="__all__") over a model using Meta.constraints:

1. Server-set constraint fields (e.g. organization) -> "<field>: required"
   on create. Partially patched by #2092 for the 5 org-attached models.
2. Client-supplied constraint fields (TableSettings, ProfileManager,
   agentic table settings, lookups) -> "...must make a unique set" raised at
   is_valid(), short-circuiting the views' intended
   `except IntegrityError: raise DuplicateData(<friendly>)` path. This both
   replaced the friendly message and moved the error from a top-level
   `detail` string into nested `non_field_errors`, which the frontend does
   not surface -> silent failures (e.g. duplicate LLM profile name, table
   settings no longer editable after first save).

Pin back to 3.14.0 to restore the known-good behaviour across the whole
unique-constraint class at once. The CVE-2024-21520 XSS patch carried by
3.15.2 is intentionally deprioritized; the 3.15 upgrade will be reattempted
later with a serializer-level fix (drop auto-derived uniqueness validators).

Reverts only the DRF entry from #2087; other batched bumps untouched. The
org `editable=False` changes (#2092) remain correct no-ops under 3.14 (org
is set server-side in save() from UserContext), so no rollback is needed there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Two pyproject.toml files downgrade the pinned djangorestframework version from 3.15.2 to 3.14.0: one in backend/pyproject.toml under the main project dependencies, and one in the root pyproject.toml under the hook-check-django-migrations dev dependency group.

Changes

DRF Version Pin Downgrade

Layer / File(s) Summary
djangorestframework pinned to 3.14.0
backend/pyproject.toml, pyproject.toml
Both files change the djangorestframework pin from 3.15.2 to 3.14.0 — one in the main backend dependencies list and one in the hook-check-django-migrations dependency group.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all critical template sections: What (dependency revert details), Why (detailed explanation of DRF 3.15 regressions with specific failure modes), How (pinning approach), breaking changes assessment, dependencies versions, and related issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and specifically identifies the main change: reverting djangorestframework to a previous version to fix UniqueTogetherValidator errors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/revert-drf-bump

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reverts djangorestframework from 3.15.2 back to 3.14.0 to unblock staging, where 3.15's new auto-derivation of UniqueTogetherValidator from Meta.constraints=[UniqueConstraint(...)] caused silent failures on several create/update flows. All four affected files (backend/pyproject.toml, backend/uv.lock, pyproject.toml, uv.lock) are updated consistently.

  • Version pinned to ==3.14.0 in both pyproject.toml files; lock files updated with correct hashes, URLs, and pytz re-added as a transitive dependency (dropped by DRF 3.15.x, required by 3.14.x).
  • The PR explicitly acknowledges that the CVE-2024-21520 XSS fix carried by 3.15.2 is intentionally sacrificed for now, with a follow-up upgrade planned.

Confidence Score: 4/5

Safe to merge as a hotfix; the revert is surgical and all four files are consistent with each other.

The change is mechanically correct — version pins match across both pyproject.toml files, lock file hashes are updated to real PyPI artifacts, and pytz is correctly re-introduced as a transitive dependency for DRF 3.14.0. The one open item is that reverting knowingly re-exposes CVE-2024-21520 (XSS in the browsable API); the team has explicitly accepted this trade-off and plans a follow-up PR, but until that lands the vulnerability window is open.

No file changes need attention beyond the acknowledged CVE trade-off; the lock files and pyproject.toml entries are fully consistent.

Security Review

  • CVE-2024-21520 (XSS, DRF browsable API): Reverting to DRF 3.14.0 re-exposes a known reflected XSS vulnerability in the browsable API renderer. The PR description explicitly acknowledges this as a deliberate, time-limited trade-off, with a follow-up upgrade planned. Actual risk depends on whether BrowsableAPIRenderer is disabled in production environments.

Important Files Changed

Filename Overview
backend/pyproject.toml Pins djangorestframework from 3.15.2 to 3.14.0; single-line, consistent with lock file update
backend/uv.lock Lock file correctly updated: package entry, hashes, URLs, and pytz re-added as a transitive dependency for DRF 3.14.0
pyproject.toml Root pyproject.toml version pin updated consistently with backend/pyproject.toml
uv.lock Root lock file updated with correct DRF 3.14.0 hashes and pytz dependency; matches backend/uv.lock changes

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["DRF 3.15.2 (was pinned)"] -->|"auto-derives UniqueTogetherValidator\nfrom Meta.constraints=[UniqueConstraint(...)]"| B["ModelSerializer is_valid()"]
    B -->|"constraint field server-set (e.g. org)"| C["400: field required on create"]
    B -->|"constraint fields client-supplied"| D["400: non_field_errors unique-set\nshort-circuits IntegrityError path"]
    D --> E["Silent failure — friendly DuplicateData\nnever raised; frontend sees nothing"]

    F["DRF 3.14.0 (this PR)"] -->|"no auto-derivation from UniqueConstraint"| G["ModelSerializer is_valid() passes"]
    G --> H["DB IntegrityError on duplicate"]
    H --> I["except IntegrityError → DuplicateData\nfriendly message surfaced to frontend"]

    style A fill:#f88,stroke:#c00
    style F fill:#8f8,stroke:#080
    style E fill:#f88,stroke:#c00
    style I fill:#8f8,stroke:#080
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["DRF 3.15.2 (was pinned)"] -->|"auto-derives UniqueTogetherValidator\nfrom Meta.constraints=[UniqueConstraint(...)]"| B["ModelSerializer is_valid()"]
    B -->|"constraint field server-set (e.g. org)"| C["400: field required on create"]
    B -->|"constraint fields client-supplied"| D["400: non_field_errors unique-set\nshort-circuits IntegrityError path"]
    D --> E["Silent failure — friendly DuplicateData\nnever raised; frontend sees nothing"]

    F["DRF 3.14.0 (this PR)"] -->|"no auto-derivation from UniqueConstraint"| G["ModelSerializer is_valid() passes"]
    G --> H["DB IntegrityError on duplicate"]
    H --> I["except IntegrityError → DuplicateData\nfriendly message surfaced to frontend"]

    style A fill:#f88,stroke:#c00
    style F fill:#8f8,stroke:#080
    style E fill:#f88,stroke:#c00
    style I fill:#8f8,stroke:#080
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
backend/pyproject.toml:22
**Known XSS exposure from CVE-2024-21520**

DRF 3.14.0 is vulnerable to CVE-2024-21520 (a reflected XSS in the browsable API). The PR description acknowledges this deliberately. Worth tracking an explicit issue/ticket for the follow-up upgrade so the window doesn't widen — the browsable API is typically disabled in production (`DEFAULT_RENDERER_CLASSES` without `BrowsableAPIRenderer`), which substantially reduces the actual attack surface, but it's worth confirming that setting is enforced in all deployed environments.

Reviews (1): Last reviewed commit: "[FIX] Revert djangorestframework 3.15.2 ..." | Re-trigger Greptile

Comment thread backend/pyproject.toml
"cryptography>=48.0.1",
"django==4.2.30",
"djangorestframework==3.15.2",
"djangorestframework==3.14.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 security Known XSS exposure from CVE-2024-21520

DRF 3.14.0 is vulnerable to CVE-2024-21520 (a reflected XSS in the browsable API). The PR description acknowledges this deliberately. Worth tracking an explicit issue/ticket for the follow-up upgrade so the window doesn't widen — the browsable API is typically disabled in production (DEFAULT_RENDERER_CLASSES without BrowsableAPIRenderer), which substantially reduces the actual attack surface, but it's worth confirming that setting is enforced in all deployed environments.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/pyproject.toml
Line: 22

Comment:
**Known XSS exposure from CVE-2024-21520**

DRF 3.14.0 is vulnerable to CVE-2024-21520 (a reflected XSS in the browsable API). The PR description acknowledges this deliberately. Worth tracking an explicit issue/ticket for the follow-up upgrade so the window doesn't widen — the browsable API is typically disabled in production (`DEFAULT_RENDERER_CLASSES` without `BrowsableAPIRenderer`), which substantially reduces the actual attack surface, but it's worth confirming that setting is enforced in all deployed environments.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

@chandrasekharan-zipstack chandrasekharan-zipstack changed the title [FIX] Revert djangorestframework 3.15.2 → 3.14.0 to unblock staging [FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors Jun 20, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/pyproject.toml`:
- Line 22: The djangorestframework dependency is pinned to version 3.14.0, which
contains CVE-2024-21520, a known XSS vulnerability in the Browsable API's header
handling. Update the version constraint for djangorestframework in the
dependencies to 3.15.2 or later to resolve this vulnerability. If upgrading is
not immediately possible due to runtime constraints, document the security risk
with a clear explanation and establish a time-bound follow-up task to complete
the upgrade.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1b1c0f69-3162-4203-8f00-015af05921f0

📥 Commits

Reviewing files that changed from the base of the PR and between de49f06 and 53016e0.

⛔ Files ignored due to path filters (2)
  • backend/uv.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • backend/pyproject.toml
  • pyproject.toml

Comment thread backend/pyproject.toml
"cryptography>=48.0.1",
"django==4.2.30",
"djangorestframework==3.15.2",
"djangorestframework==3.14.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Confirm CVE-2024-21520 details for Django REST Framework: affected versions, first patched version, exploit conditions, and official mitigations/workarounds.

💡 Result:

CVE-2024-21520 is a Cross-site Scripting (XSS) vulnerability affecting the Django REST Framework (DRF) [1][2]. Affected Versions: All versions of the djangorestframework package prior to 3.15.2 are vulnerable [1][2]. First Patched Version: The vulnerability was resolved in version 3.15.2 [1][3]. Exploit Conditions: The vulnerability exists in the break_long_headers template filter used within the Browsable API [4][5]. It occurs due to improper input sanitization of headers before they are split and joined with
tags in the template [1][6]. An attacker could potentially exploit this if they can control header content (e.g., via a Location header or other response headers) that is then rendered by the Browsable API [4]. Official Mitigations/Workarounds: The official mitigation is to upgrade to Django REST Framework version 3.15.2 or later [1][2]. The fix works by ensuring that the header input is properly escaped using the escape function before it is processed by the template filter [4][5]. There are no widely recommended alternative workarounds other than upgrading the package [1][3].

Citations:


Address CVE-2024-21520 XSS vulnerability in djangorestframework 3.14.0.

Pinning to djangorestframework==3.14.0 introduces a known Cross-site Scripting (XSS) vulnerability (CVE-2024-21520) in the Browsable API's header handling. This vulnerability exists in all versions prior to 3.15.2, where it was fixed. Either upgrade to 3.15.2 or later, or if a downgrade is unavoidable for runtime constraints, document the risk and establish a time-bound follow-up to remediate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/pyproject.toml` at line 22, The djangorestframework dependency is
pinned to version 3.14.0, which contains CVE-2024-21520, a known XSS
vulnerability in the Browsable API's header handling. Update the version
constraint for djangorestframework in the dependencies to 3.15.2 or later to
resolve this vulnerability. If upgrading is not immediately possible due to
runtime constraints, document the security risk with a clear explanation and
establish a time-bound follow-up task to complete the upgrade.

@github-actions

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
unit-connectors unit 64 12 0 3 16.8
unit-core unit 0 0 4 0 1.2
unit-platform-service unit 9 0 1 0 1.4
unit-prompt-service unit 15 0 0 0 20.5
unit-rig unit 53 0 0 0 3.4
unit-runner unit 11 0 0 0 3.1
unit-sdk1 unit 390 0 0 0 20.7
unit-tool-registry unit 0 0 1 0 1.3
unit-workers unit 0 0 0 0 17.8
TOTAL 542 12 6 3 86.1

Critical paths

⚠️ Critical paths not yet covered

  • auth-login — User can log in and obtain a session cookie. (entry: POST /api/v1/auth/login; declared coverage: no groups declared)
  • adapter-register-llm — Register and validate an LLM adapter. (entry: POST /api/v1/adapter/; declared coverage: no groups declared)
  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (entry: POST /api/v1/workflow/{id}/execute/; declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (entry: POST /deployment/api/{org}/{name}/; declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (entry: POST /api/v1/prompt-studio/prompt-studio-tool/{id}/fetch_response/; declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (entry: POST /api/v1/pipeline/{id}/execute/; declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (entry: GET /api/v1/usage/get_token_usage/; declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (entry: internal: backend → rabbitmq → workers/file_processing; declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (entry: internal: workers/callback → backend /internal endpoints; declared coverage: no groups declared)
✅ Covered critical paths
  • tool-sandbox-exec — covered by unit-runner

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.

1 participant