Skip to content

Harden the default Content-Security-Policy: use a per-request nonce instead of 'unsafe-inline' / 'unsafe-eval' #10425

Description

@asheshv

Summary

pgAdmin 4's default CONTENT_SECURITY_POLICY allowed 'unsafe-inline' and 'unsafe-eval' in script-src, which leaves the policy unable to stop an injected inline script — the main protection a CSP is meant to provide.

Inline scripts now run under a per-request nonce instead:

  • A per-request nonce is generated with secrets.token_urlsafe and cached on flask.g, so the same value is emitted in the templates and in the CSP response header.
  • A {nonce} placeholder in CONTENT_SECURITY_POLICY is substituted at runtime.
  • Inline <script> and <style> tags carry the nonce.
  • The new default is script-src 'self' 'nonce-{nonce}', with neither 'unsafe-inline' nor 'unsafe-eval'.

Two deliberate limits:

  • style-src keeps 'unsafe-inline'. MUI and React inject runtime styles and inline style="" attributes that cannot carry a nonce.
  • Development bundles are built with webpack's eval devtool, which a strict nonce policy blocks. get_content_security_policy() appends 'unsafe-eval' to script-src automatically when config.DEBUG is set and the policy uses a nonce, so developers no longer have to add it by hand in config_local.py. Production is unaffected, and a custom non-nonce policy passes through untouched.

Fix

Fixed in pgAdmin 4 9.18 by commit fb0ca5c4c.

Unit tests cover nonce generation, caching and per-request freshness, {nonce} substitution, pass-through of custom/None/empty policies, header emission, and the development-mode behaviour.

Not a vulnerability report

This is a hardening change to pgAdmin's own default policy rather than a fix for a reported flaw, so no CVE has been requested.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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