feat(security-headers): make CSP connect-src/form-action configurable (BUNYIP-244) #19
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/BUNYIP-244-configurable-csp"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Make the
dunite-coreSecurityHeadersCSP configurable instead of emitting a single hardcoded policy, so a consumer can allowlist the cross-origin destinations its flows legitimately need (an OAuth clientredirect_uriorigin, a public API origin) onconnect-src/form-actionwithout forking the policy or naming any app in the generic crate. Closes the dunite half of BUNYIP-244.Changes
CspConfig { connect_src, form_action }andSecurityHeaders::with_csp(cfg)(plus::new()/Default). The CSP header is built once at construction; supplied origins append only toconnect-src/form-action, every other directive stays locked down.SecurityHeadersbecomes a struct carrying the precomputedHeaderValue. Existing.wrap(SecurityHeaders)call sites must move toSecurityHeaders::new()(done in the bunyip PR).Coordination: overlaps BUNYIP-235
The open
fix/BUNYIP-235-csp-form-action-stripebranch edits the SAME directive, addingcheckout.stripe.com/billing.stripe.comtoform-action(the subscribe / billing-portal flows 302 to those, which CSP3 appliesform-actionto). To avoid regressing it regardless of merge order, this PR folds those Stripe origins into the configurable base, so the default policy keeps them and consumer origins append on top. Whichever of the two merges second resolves a one-line conflict on that directive (both want Stripe in the base; this PR additionally makes it appendable).Verification
cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warnings, andcargo test --workspaceall green in therust-builder-glibc:v1.0.1-rust1.94-trixiecontainer (84 tests pass, incl. new coverage for append, fail-closed, and the Stripe-default form-action).The SecurityHeaders middleware emitted a single hardcoded, Stripe-only Content-Security-Policy. A consuming app whose flow legitimately reaches a cross-origin destination (an OAuth client redirect_uri origin, a public API origin distinct from the serving origin) had no way to allowlist it without forking the policy string, and the blocked request surfaced as a CSP violation that looks like an outage. Add CspConfig { connect_src, form_action } and SecurityHeaders::with_csp(cfg). The middleware now builds the CSP header once at construction, appending the supplied origins only to connect-src / form-action; every other directive stays locked down. An empty config (SecurityHeaders::new / ::default) reproduces the previous static policy byte-for-byte, and an origin that would yield an invalid header value fails closed to the locked-down default. The crate stays app-agnostic: origins arrive as data, no app or brand is named. #BUNYIP-244