Skip to content

Footgun when accessing nonce value in a middleware #247

@alynn-coefficient

Description

@alynn-coefficient

django-csp only generates the nonce value (and includes it the header) the first time that .csp_nonce is accessed on a request. However, if that's accessed first in a middleware after django-csp has completed, it'll be generated but not included in the header, because django-csp has already finished processing and sendings its headers. Slightly more concretely, if we have:

MIDDLEWARE = [
    ...
    "foo.bar",
    "csp.middleware.CSPMiddleware",
    ...
]

And foo looks something like:

def bar(get_response):
    def middleware(request):
        response = get_response(request)
        response = inject_script_into_response(response, nonce=request.csp_nonce)
        return response
    return middleware

The script will correctly have a CSP nonce in it, but the CSP header won't necessarily include the nonce because of the position of CSPMiddleware.

Obviously the fix is on the user here and "foo.bar" should be positioned after the CSP middleware, however I can attest this took a while to track down. I think it would be better to make this a hard error if a CSP nonce doesn't already exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions