Opened 3 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#36831 closed Cleanup/optimization (wontfix)

Add validation for CSP directive names and values in build_policy()

Reported by: Naveed Qadir Owned by: Naveed Qadir
Component: Utilities Version: 6.0
Severity: Normal Keywords: csp, validation
Cc: Naveed Qadir Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Naveed Qadir)

The build_policy() function in django/utils/csp.py does not validate directive names or values, allowing malformed CSP policies to be generated.

Problem

CSP policies use semicolons to separate directives. If a directive name or value contains a semicolon (e.g., from a misconfiguration), it can result in a malformed policy:

from django.utils.csp import build_policy, CSP

# This produces a malformed CSP header
policy = {"script-src": ["https://good.com; report-uri https://evil.com"]}
build_policy(policy)
# Returns: "script-src https://good.com; report-uri https://evil.com"
# The semicolon splits what should be one directive into two!

While this requires developer misconfiguration (not user input), it's a hardening improvement to catch these errors early with a clear error message rather than silently producing invalid policies.

Solution

Add validation to build_policy() that raises ValueError if:

  • Directive names contain semicolons, \r, or \n
  • Values contain semicolons

The error messages guide developers to use proper list syntax for multiple values.

Patch

A patch with tests is ready and is submitted as a PR.

Change History (3)

comment:1 by Naveed Qadir, 3 weeks ago

Description: modified (diff)
Keywords: csp validation added
Owner: set to Naveed Qadir
Status: newassigned

comment:2 by Jacob Walls, 3 weeks ago

Resolution: wontfix
Status: assignedclosed

Thanks for the ticket, but I don't think this brings enough value to work on. There's developer feedback in browser dev tools already for invalid policies:

98:1 Unrecognized Content-Security-Policy directive 'foo'.

And I'm not certain some of the proposed validations aren't technically valid somehow.

What are your motivations for opening this report?

in reply to:  2 comment:3 by Naveed Qadir, 3 weeks ago

Thanks for reviewing, Jacob. I understand the concern about adding validation that might be overly restrictive.

My motivation was to catch developer errors earlier in the development cycle (during testing/local development) rather than requiring manual inspection of browser console logs. The specific scenario: developer misconfigures CSP with embedded semicolons → Django silently generates malformed policy → browser partially applies it, security gaps may go unnoticed.

Regarding technical validity: semicolons in directive names are definitively invalid per the [CSP Level 3 spec](https://www.w3.org/TR/CSP3/#grammardef-serialized-policy), which defines directive names as tokens that cannot contain semicolons (reserved as directive separators).

If there's interest in a minimal approach validating only directive names against the spec's well-defined grammar, I'm happy to revise. Otherwise, I understand closing as wontfix.
Replying to Jacob Walls:

Thanks for the ticket, but I don't think this brings enough value to work on. There's developer feedback in browser dev tools already for invalid policies:

98:1 Unrecognized Content-Security-Policy directive 'foo'.

And I'm not certain some of the proposed validations aren't technically valid somehow.

What are your motivations for opening this report?

Note: See TracTickets for help on using tickets.
Back to Top