-
-
Notifications
You must be signed in to change notification settings - Fork 446
Content Security Policy (CSP) Implementation a new approach #4776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
I like the different Input fields, but I would have tried it with less classes. (I might try to get it working in my MR) One of the reasons why I wanted the layout update approach was so I could enable different urls depending on the page. Like if Captcha is enabled and it uses external source, I could enable it only for the ones with captcha. |
Hey @Hanmac, thanks for your work and inspiration!
In my view, CSPs should be set at the controller level, where the response and its headers are handled. |
@Hanmac, it’s not exactly what you wanted, but I’ve added the option to include directives via |
Awesome, work guys! CSP is the only real way to stop MageCart style attacks so this is major. I think allowing the rules to be added via layouts and events is useful so that extensions can inject their CSP policies without overriding controllers or requiring manual update to the config or global config. For example, you may want an obnoxious add-on the main site, but exclude it from the checkout or account pages, or it may only apply to product pages (e.g. a reviews plugin) so adding it everywhere just bloats your header sizes. Keep in mind that some third-party add-ons don't just require a single rule, some of the worst ones may require a bunch of rules (Facebook is one of the worst if I recall correctly). |
These are both big PRs so it is hard to review and compare without a deep dive.. @Hanmac you are very clearly credited in the description of the PR, does it matter whose PR is finally merged? If you truly think this is a worse PR than yours then just state the reasons so everyone can understand and help decide. But, if you think it is generally an improvement or at least can live with the changes and recognize that to some users it may be an improvement, then just get onboard and help iron out the issues on this PR and close yours - everyone will still recognize the hard work you put into laying the foundation and getting it to completion. |
Cant create a PR to your repo ... PhpSran Level 10 ... https://github.com/OpenMage/magento-lts/commit/8b501d87d611f42376acd10c68c0318194046ca5.patch Please check commented lines. |
I've added a default setting to convert and merge all This allows adding: <checkout_onepage_index>
<reference name="csp_meta">
<action method="addDirective"><directive>default-src</directive><value>*.default-from-layout-update.com</value></action>
<action method="addDirective"><directive>script-src</directive><value>*.script-from-layout-update.com</value></action>
<action method="addDirective"><directive>style-src</directive><value>*.style-from-layout-update.com</value></action>
</reference>
</checkout_onepage_index> Then they are read and added here, and the block output is disabled: if ($helper->shouldMergeMeta($area)) {
$blockCspMeta = Mage::app()->getLayout()->getBlock('csp_meta');
if ($blockCspMeta && $blockCspMeta instanceof Mage_Csp_Block_Meta) {
$metaDirectives = $blockCspMeta->getDirectives();
foreach ($metaDirectives as $directive => $values) {
$directives[$directive] = array_unique(
array_merge($directives[$directive] ?? [], $values),
);
}
}
} |
@empiricompany the only tricky one is this Route: But you could add it to |
@Hanmac For the |
Yeah, that's what i mean. But if i would enable, |
Please grant permission to create PRs. I'd like to add some tests. Two small bugs in admin config:
|
Some code could be shorter, but .... https://youtrack.jetbrains.com/issue/WI-81337/Argument-type-does-not-match-the-declared-when-using-class-alias |
Co-authored-by: Sven Reichel <[email protected]>
sure, you can create PR on my branch |
~ use config path instead of NodePath
My checklist for next days :) |
See latest commits https://github.com/sreichel/magento-lts/tree/Mage_Csp |
strange, if you look there is also a PR of @Hanmac that I have just merged |
I somehow had the same problem, but i don't remember how i fixed it. I think I changed it to myRepo:Mage_Csp <= empiricompany:Mage_Csp, @sreichel you can try to click on this Link: empiricompany/openmage@Mage_Csp...sreichel:magento-lts:Mage_Csp |
@sreichel simply fork my branch https://github.com/empiricompany/openmage/tree/Mage_Csp and create a pull request |
@empiricompany thats what I did. I'll test it again. |
Content Security Policy (CSP) Implementation in OpenMage
This PR adds comprehensive support for Content Security Policy (CSP) headers in OpenMage, significantly improving application security against XSS attacks and other client-side security vulnerabilities. The module was developed based on the PR #4753 by @Hanmac, to whom all credit should be given. I decided to create a completely separate PR because there were many changes and the approach is very different. I don't want to impose my solution but rather propose a more robust implementation following the OpenMage standards that guarantees the same functionality, such as the ability to specify directives per module and the separation of frontend and backend directives.
Features
Modular configuration: Each module can specify its own CSP directives in the default section areas:
global/csp/<directive-name>
: Applied to both frontend and backendfrontend/csp/<directive-name>
: Applied only to the frontendadminhtml/csp/<directive-name>
: Applied only to the backend (administration panel)Administration interface: Administrators can:
IMPORTANT: Read this https://content-security-policy.com/examples/multiple-csp-headers/
<global />,
<frontend />
,<admihtml />
)Pre-configured security: The module includes safe directives in the global section (like 'self' for most directives) providing a secure baseline configuration
Support for all standard CSP directives:
Advantages of This Approach
The key technical advantages of this implementation include:
http_response_send_before
ensures headers are applied at the optimal moment in the request lifecycle while preventing themes from injecting potentially malicious directivesConfiguration Example in a Module
Modules can specify CSP directives in their
config.xml
file in three different areas. This configuration approach follows the same pattern used forglobal>ignore_user_agents
in OpenMage:Each directive can have multiple entries, and they will be properly merged with directives from other modules and user configurations.

You can see for each directive in which area it was added:
Resources
Open Questions
Ability to add directives from views
The ability to add directives from the presentation layer was deliberately left out. It could be easily implemented, but IMHO views should not have this kind of "power". In cases where themes include external resources, directives can be easily added by checking the browser console.
= UPDATE =
I implemented support for adding directives via
<meta>
, but it’s strongly discouraged according to the documentation.For this reason, all
<meta>
directives added via layout update are merged into the HTTP header by default. If you want to enable directive insertion through<meta>
, you must explicitly it in the configuration.It’s possible to add them through a layout update like this:
This will print in the head (in report-only or enforce mode according to the configuration):
These directives will be difficult to debug because they won’t appear in the configuration like those declared by the modules.
IMPORTANT: Read this https://content-security-policy.com/examples/meta/
API Responses and Event Handling
CSP headers are currently added to all responses, including API responses, by observing the
http_response_send_before
event. This shouldn't create problems since CSP directives are only interpreted by browsers and add minimal overhead to API responses.However, it raises the question:
Is it better to hook into an event that only affects frontend/HTML responses, or is it preferable to have CSP headers consistently applied to all responses regardless of type?
Netalico solution use "controller_action_predispatch"
https://github.com/netalico/magento-1-csp/blob/master/app/code/local/Netalico/Csp/etc/config.xml
Report URI Implementation
The current implementation include configuration for a
report-to
directive declared inReporting-Endpoints
header, which could be valuable for collecting violation reports to external service like https://report-uri.com.Future enhancements could include:
Enforce only specific frontend area
I'm thinking about implementing the possibility to enable CSP enforcement only in specific areas, for example on the checkout_onepage_index controller — although I'm not sure I'll go through with it, since I believe the entire site should include security headers.
Default directives
Does it make sense to include default directives for services like Google Analytics, PayPal, Stripe, etc.?
These can change over time and there will never be a complete list — it will always be specific to each use case.
It feels like the same discussion we had about
ignore_user_agents
.Nonce helper
A nonce helper could also be implemented to use in the views for scripts and automatically add it to the directives.
Resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP#nonces