#9613·logto

Make experience CSP directives configurable (strict CSP for self-hosted OSS)

Author: jonathan-m-borgesCreated Sep 16, 2026Updated Sep 16, 2026

What problem did you meet?

The experience CSP is hardcoded in packages/core/src/middleware/koa-security-headers.ts. Security scanners (OWASP ZAP) and external pentests consistently flag the resulting policy on self-hosted deployments:

  • CSP: Wildcard Directive — https: allowed in style-src, img-src, frame-src, font-src
  • script-src 'unsafe-inline' / 'unsafe-hashes'
  • style-src 'unsafe-inline'

These are rated Medium/High by scanners and must be formally risk-accepted in compliance programs (ISO 27001, SOC 2, client TPRM questionnaires), since there is no configuration path: customUiCsp only appends sources, and no env var / DB config can restrict or override directives. The frame-src: https: case is even marked WARNING (high risk) in the source itself.

Describe what you'd like Logto to have

A supported way for self-hosted operators to tighten the experience CSP, e.g.:

  1. Allow customUiCsp (or a new sign-in experience / env setting) to replace directives instead of only appending; or
  2. A "strict CSP" opt-in flag that swaps wildcard sources for an operator-provided allowlist (branding assets, connector origins), and
  3. Longer term: nonce/hash-based script-src/style-src in the experience app so unsafe-inline/unsafe-hashes can be dropped.

Describe alternatives you've considered

  • Header rewrite at the edge (Application Gateway/CDN): works for wildcards but cannot remove unsafe-inline/unsafe-hashes (the experience genuinely uses inline scripts/styles — removing them breaks sign-in), and drifts on every upgrade.
  • Forking/patching the image: unsustainable maintenance burden.
  • Formal risk acceptance: what we do today, but configurability at the source is the right fix.