Skip to content

feat: make CSRF cookie and header names configurable#3745

Draft
yosofbadr wants to merge 2 commits intoplotly:devfrom
yosofbadr:feature/configurable-csrf-token
Draft

feat: make CSRF cookie and header names configurable#3745
yosofbadr wants to merge 2 commits intoplotly:devfrom
yosofbadr:feature/configurable-csrf-token

Conversation

@yosofbadr
Copy link
Copy Markdown

Summary

  • Add csrf_token_name and csrf_header_name config options to the Dash constructor
  • Allows users to match the CSRF cookie/header names used by their server framework (e.g. Django uses csrftoken instead of _csrf_token)
  • Values flow through Dash's standard config pipeline: Python app.config -> HTML _dash-config JSON -> frontend Redux store
  • getCSRFHeader() now reads cookie/header names from config with backward-compatible defaults
  • When the configured CSRF cookie is absent, no header is sent (previously sent undefined value)

Usage

# Django users
app = Dash(__name__, csrf_token_name="csrftoken")

# Custom CSRF setup
app = Dash(__name__, csrf_token_name="my_csrf", csrf_header_name="X-My-CSRF")

# Default behavior unchanged
app = Dash(__name__)  # uses '_csrf_token' / 'X-CSRFToken'

Motivation

Dash's frontend hardcodes the CSRF cookie name as _csrf_token, which conflicts with Django's default csrftoken. Users embedding Dash in Django apps with CSRF middleware enabled cannot use Dash without project-wide Django config changes. See #729 for full history.

This follows the architecture recommended by @chriddyp in #729: config variables should flow through Dash's standard config pipeline, not through hooks.

Prior art

PR #990 attempted this via the hooks system but was closed without review. This PR instead uses the config pipeline as maintainers requested.

Files changed

File Change
dash/dash.py Added params, config, validation, read-only, docstrings
dash-renderer/src/actions/index.js getCSRFHeader(config) with dynamic cookie/header names
dash-renderer/src/actions/api.js Pass config through GET/POST
dash-renderer/src/actions/callbacks.ts Pass config to getCSRFHeader
dash-renderer/src/config.ts Added optional fields to DashConfig type
tests/unit/test_configs.py 7 unit tests (defaults, custom, HTML output, validation, read-only)
CHANGELOG.md Added entry under UNRELEASED

Test plan

  • Unit tests for default config values
  • Unit tests for custom config values
  • Unit tests verifying config appears in generated HTML
  • Unit tests for input validation (empty/whitespace rejected)
  • Unit tests for read-only enforcement
  • Validated with Django 6.0 + CsrfViewMiddleware active
  • Renderer builds successfully
  • ESLint + Prettier pass on all JS/TS changes
  • Black + flake8 pass on all Python changes
  • CI integration tests

Fixes #729

Add `csrf_token_name` and `csrf_header_name` config options to the Dash
constructor, allowing users to match the CSRF cookie/header names used
by their server framework (e.g. Django uses 'csrftoken').

The values flow through Dash's standard config pipeline: Python
`app.config` -> HTML `_dash-config` JSON -> frontend Redux store.
`getCSRFHeader()` now reads these from config with backward-compatible
defaults ('_csrf_token' / 'X-CSRFToken'). When the configured cookie
is absent, no CSRF header is sent (previously sent undefined value).

Fixes plotly#729
@yosofbadr yosofbadr marked this pull request as draft April 15, 2026 19:17
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.

Name of CSRF cookie is hard-coded.

1 participant