mulertech/csp-bundle
Symfony bundle for managing Content Security Policy headers. Configure policies, nonces, and directives from YAML, then automatically apply CSP headers to responses with support for reporting and per-route rules.
Architecture fit. This package owns a narrow, well-bounded concern: constructing a Content-Security-Policy header for Laravel responses. The v3.2.0 release does not change that architecture. It adds one optional builder argument and refines how a single directive (upgrade-insecure-requests) is conditioned on the request host. The change is additive and stays inside the existing policy-construction seam (builder → event → middleware/response header), so it is a clean fit for any Laravel app that already emits CSP via headers rather than meta tags.
Integration feasibility. Very high. The default behaviour is unchanged: existing calls to CspHeaderBuilder::build() with no arguments produce the same policy as before. The new plainLoopbackOrigin argument is opt-in. The bug fix (omitting the directive on plain-HTTP loopback hosts) requires no application code changes — it is automatic. The only integration work is optional: teams whose local dev server is reached under a different name (app.test, a LAN IP, a container hostname) must follow the documented escape hatch (upgrade-insecure-requests: false under when@dev).
Technical risk. Low, with two areas to note:
trusted_proxies appearing as plain HTTP. The second case means an app behind a misconfigured proxy will keep upgrade-insecure-requests — correct from a security standpoint, but it can surface as a real production breakage if the proxy config is wrong and the site is served over HTTP. This is a pre-existing condition made more legible, not a new risk introduced by the release.BuildCspHeaderEvent is sent as the listener wrote it" is a behavioural clarification with real weight: listener output now wins verbatim. Teams that use the event to post-process the builder's output should confirm their listener still receives what they expect.Key questions.
plainLoopbackOrigin a public API we intend to support long-term, or an internal/test affordance? What is its documented default and is it nullable?Request::getHost(), and does it honour trusted_proxies for that resolution? The notes imply yes — confirm in code review.block-all-mixed-content), or is upgrade-insecure-requests the only Safari divergence?localhost, *.localhost, 127.0.0.0/8, ::1) and the two negative cases (public host on HTTP, proxy missing from trusted_proxies)?Stack fit. No framework-version implications are stated. The change touches request-host inspection and header construction only — surfaces stable across supported Laravel versions. Confirm the minimum supported Laravel/PHP versions remain accurate in composer.json and that the loopback CIDR check for 127.0.0.0/8 and ::1 uses a dependency already present rather than a newly added one.
Migration path. There is no migration. Upgrade by bumping the constraint to ^3.2. Two verification steps:
localhost by default, so a previously-passing header assertion may now legitimately differ).Compatibility. Backward compatible by the release's own statement (existing calls unaffected). The forward-compatibility caveat is the BuildCspHeaderEvent clarification: if any listener previously mutated a policy expecting the middleware to modify it afterwards, that expectation should be re-read against the new guarantee.
Sequencing. Low urgency, low coordination cost:
app.test, LAN addresses) — this is the step most likely to be skipped and most likely to cause a repeat of the original confusion.trusted_proxies configuration in staging so the host-based exemption behaves as expected there.Maintenance. Minimal. One optional parameter and one conditional directive; both are isolated. The main ongoing cost is documentation drift — the dev-exemption behaviour is the kind of thing that gets re-litigated by the next engineer who sees an unstyled Safari page and does not know the directive was already handled.
Support. Expect a small, predictable class of support questions: "my CSP is different in dev than prod" and "Safari is broken on my dev server at app.test." The README addition addresses the second directly; the first is answered by understanding the host-based rule. Worth a line in internal runbooks.
Scaling. No scaling implications. Header construction is per-response and trivially cheap; the loopback check is a string/CIDR comparison against a value already resolved by the framework.
Failure modes.
upgrade-insecure-requests: false under when@dev). This is the primary residual failure mode and it is a documentation-dependent fix.trusted_proxies — framework sees plain HTTP; because the exemption is host-based, the public host still gets the directive, so this fails safe (secure) rather than failing open. Good design, but it means the underlying proxy misconfiguration can persist unnoticed.localhost. Detectable and cheap to fix.Ramp-up. Near zero for developers who only consume the default behaviour. For whoever owns security headers, the required knowledge is: the directive is dropped only for plain-HTTP loopback hosts, the decision reads host not scheme, and there is an explicit opt-out for non-standard dev hostnames. That is a short brief, and the release notes and README together cover it. A team already carrying a bespoke CSP workaround for the Safari dev issue can retire it after upgrading — that is the clearest operational win in this release.
How can I help you explore Laravel packages today?