Skip to content

form-action 'self' in nginx CSP breaks SAML HTTP-POST binding redirects #1052

Description

@mmguero

Summary

The CSP hardening added to the nginx proxy layer (as part of the third-party security assessment remediation) includes:

# Block clickjacking and restrict base/form targets; does not affect script/style execution
add_header Content-Security-Policy "frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;
# Legacy clickjacking fallback for browsers that don't honor CSP frame-ancestors
add_header X-Frame-Options "SAMEORIGIN" always;

A user has reported that form-action 'self' breaks SAML authentication. SAML's HTTP-POST binding relies on the browser auto-submitting a form to the IdP's origin (and back to our ACS endpoint on return) — form-action 'self' blocks that cross-origin form submission by design. This is the policy working as intended, just incompatible with POST-binding SSO.

Root cause

Not a bug in the directive, but a conflict between strict form-action and any auth flow (SAML, and potentially others) that relies on cross-origin form POSTs.

Fix

We shouldn't disable the whole CSP block via a blanket env var, because frame-ancestors and base-uri are unrelated to this issue and should stay locked down unconditionally.

Instead, we should scope the fix to form-action only:

  1. Add an env var, e.g. NGINX_CSP_FORM_ACTION_EXTRA representing a space-separated list of additional allowed origins (the SAML IdP base URL(s)).
  2. Template the CSP header at container start instead of a static add_header line:
add_header Content-Security-Policy "frame-ancestors 'self'; base-uri 'self'; form-action 'self' ${form_action_extra};" always;
add_header X-Frame-Options "SAMEORIGIN" always;
  1. Document usage: users running SAML set this to their IdP's exact origin (e.g. https://idp.example.com).

Before merging

  • Confirm via browser console CSP violation report that form-action is actually the blocking directive (not connect-src or something else layered on top of a JS/meta-refresh redirect). The violation report names the directive explicitly.
  • Confirm whether the IdP redirect is genuinely cross-origin POST-binding, or proxied through our own domain first (in which case the real fix may be elsewhere).

Acceptance criteria

  • frame-ancestors 'self' and base-uri 'self' remain hardcoded and unconditional in all deployments
  • form-action allows additional origins only when NGINX_CSP_FORM_ACTION_EXTRA is set
  • Default behavior (env var unset) is unchanged from current hardened state
  • SAML login flow verified working end-to-end with the reporting user's IdP
  • Env var documented in README / config docs

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestnginxRelating to Malcolm's use of nginxregressionIt worked at one point...securityRelated to issues with bearing on the security of Malcolm itself

Type

Fields

Frequency

None yet

Projects

Status
Testing

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions