nelmio / NelmioSecurityBundle

Adds extra security-related features in your Symfony application
https://symfony.com/bundles/NelmioSecurityBundle/
MIT License
651 stars 85 forks source link

Add mechanism to modify directives during or after request handling #347

Open martijnc opened 4 months ago

martijnc commented 4 months ago

The bundle CSP configuration is parsed and injected into ContentSecurityPolicyListener directly during container building. This all happens before request handling starts, and the directive sets are not directly accessible from the container (though you can get them through ContentSecurityPolicyListener::getReport and ContentSecurityPolicyListener::getEnforcement) making it difficult to modify the directives during request handling.

I would like to propose an interfaced directive set builder to improve this. Instead of injecting the directive sets, ContentSecurityPolicyListener would receive the builders. The bundle would provide a default builder that constructs the sets based on the current configuration. Consumers who wish to modify the directives can decorate or override the default builder to supply their own directive sets or adjust the bundle-provided ones.

Use Case

We have websites that regularly run temporary marketing campaigns. These campaigns often require third-party content that needs to be allowed in the CSP policy. The current bundle configuration approach has two disadvantages here:

  1. It requires us to change, test, and roll out CSP changes to production on short notice;
  2. Once a campaign ends, there is often no incentive to remove the now outdated CSP rules, resulting in them being included much longer than required.

A mechanism that allows modification of the directive sets during request handling (e.g., in a controller, kernel event, etc.) would allow us to have a set of temporary directives that we can include as needed, based on logic in our application (e.g. from a database with start & end date), while having the bundle configuration as a restrictive baseline.

This approach would also unlock page/URL-specific configuration as requested in issues #234 and #206, but through custom application code rather than configuration.