pgadmin-org / pgadmin-org/pgadmin4

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

Open
#10,425 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.8k
Forks
891
Avg merge
4d 7h
Merged PRs (30d)
8

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The requested hardening is already recorded as fixed by commit fb0ca5c4c in pgAdmin 4 9.18. Review that commit and its unit tests, which cover nonce generation and caching, policy substitution, header emission, custom policies, and development-mode behavior; no newcomer implementation work remains on this issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python, react, webpack
Domain
security, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.