-
Notifications
You must be signed in to change notification settings - Fork 153
Content Security Policies #202
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
Conversation
To support a (useful) CSP in the current state of Magento, we'd have to allow
Those 2 escape hatches effectively nullify (most of) the value of a CSP. (Opinion) Any plan for a CSP in core should include a plan for tackling those problems. |
I'm not sure if this strategy will provide value as a default. As an attacker, it shouldn't be hard to spam the endpoint with dummy data 10k times to hide more nefarious activity in the logs. Developers can obviously customize this default, but good defaults are important for a security feature. Imagine an attacker running this code locally (pseudo-code): for i = 1 to 10000:
http.post('${magento-store-url}/csp-endpoint', fakePayload)
## logs of any prior bad activity are now purged
end for |
I agree that our need to allow |
The proposed limit is only there to limit the storage usage and prevent DoS attacks. It is assumed that developers that care about CSP will use restricted mode instead of report-only mode so there would be no incentive for an attacker to flood the reports to hide their attacks since their attacks would be blocked by CSP anyway. |
Enabling SCP in restricted mode depends on not only merchants and their SI but on 3rd party extensions installed on merchant's websites as they should be updated to support SCP before enabling restricted mode. |
we set event listener via attributes and we use eval in template.js so we'd have to also allow | ||
'unsafe-inline' and 'unsafe-eval'. Magento has integrations with multiple 3rd party services like vimeo, youtube, | ||
google analytics and various payment systems which we must whitelist additionally. | ||
That will be the default whitelist Magento provides out of the box packaged alongside related modules via _csp\_whitelist.xml_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each module should provide own scp_whitelist.xml
for 3rd party resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is what I meant
|
||
CSP API/SPI will consist of the following interfaces: | ||
|
||
* Policy DTO. The interface has only policy ID because not all CSP policies look like _\<policy name\> \<value\> \<value\>_, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you provide some details about different policy formats? I did not find any information about it in RFC. Or are you talking about serialized SCP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
examples would include plugin-types
, report-to
, sandbox
and some other policies that either require additional headers to work or at least accept different values than URIs and preserved 'self'/'unsafe-inline' words like *-src policies do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably I'm not clear understand but plugin-types
, report-to
, sandbox
have the same format <policy name/> <value/> <value/>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got confused, thought the question was related to the limitation of available policies through csp_whitelist.xml - for that file allowed options for values are important as well. report-to
requires additional header and Subresource Integrity may involve Access-Control-Allow-Origin
header to be implemented
} | ||
``` | ||
|
||
* A repository of violations logs collected when CSP reporting is enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to think how to make reporting works. I don't think we can't use Web API to capture the data, it would be just too much load. May need to build a separate service for capturing reports data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can use a regular controller as the report endpoint for browsers if our web API mechanism would be difficult to fit for this
AngularJs provides a possibility to define SCP on a view level (directly in HTML), maybe this approach would allow us to avoid global usage of |
I understand that but if a merchant wants to enable CSP they can compensate for unsafe extensions by whitelisting resources those extension use themselves or make other changes to active policies |
there is no way to use only certain policies for a portion of a page. If in the future we disable 'unsafe-inline' and a 3rd party-developer would need to reenable it for a specific page they would be able to do so with CSPAwareActionInterface |
@zetlen can we make sure this is incorporated into our approach for PWA? Better to do this sooner than later for the product since this affects content. Thanks! |
re: whitelisting, Google has a research paper where they analyzed and documented the effectiveness of deployed CSPs on the web. I'm not finished reading through it yet (but will be :D), but this quote in the intro stood out:
https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/45542.pdf Note that the alternative proposed in the paper's intro ( |
that is an interesting point. This document is more focused on introducing CSP to Magento and allowing merchants/developers to configure policies, actual policies supplied by default with core Magento are up for debate |
I don't think this comment has received enough attention. As it stands now, if the user has to enable these options and effectively open a huge hole in the security (and therefore the purpose) of this feature, is it worth implementing now without a solid plan to go with it? |
Added a bit about strategy going forward and whitelisting with nonce |
@DrewML @joni-jones do you have any objections? |
Even with the added changes to the plan moving forward, I still have concerns about the false sense of security that this feature would provide in its current state. I understand that something is better than nothing in many cases but I think this would leave users way more vulnerable than they would feel they are. A large number of the security bugs that have been resolved in the current security remediation effort were related to eval. If we are knowingly using vulnerable libraries and the desire is to avoid the vulnerable feature, we should have an active plan to mitigate the risk. We deprecated the entire Magento Backups feature because of similar concerns. We shouldn't be in such a rush to push a feature forward that we compromise on security especially when that is the entire point of the changes. As a side note, I think it would be good to have the security team review security-related PR's as well as they may have some existing research to share. |
design-documents/csp.md
Outdated
|
||
It is possible to combine nonce and domain-list based whitelisting for CSP. | ||
|
||
Magento will have to generate unique nonce (using _Magento\Framework\Math\Random_) for each response and developers will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Magento/Framework/Math/Random
cryptographically secure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, at the core it uses random_int
which is.
design-documents/csp.md
Outdated
To make it easier for developers and don't force them to include the nonce-helper to all of their blocks it will | ||
be available inside _.phtml_ templates via local `$nonce` variable. | ||
|
||
Additional effort will have to go to ensure proper nonce used/regenrated when page cache is enabled. Perhaps blocks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to spend more time on this section before merging this.
Additional effort will have to go to ensure proper nonce used/regenrated when page cache is enabled
Magento only has good performance in production with Varnish, and the nonce
must be delivered in the response. If we were to release this without a full solution for caching, most merchants will take the speed and security they have today, rather than more security and massive performance regressions.
We need a plan for how we're going to deliver a unique nonce
per request without disabling Varnish.
design-documents/csp.md
Outdated
|
||
## Future steps | ||
To allow merchants to use whitelisting with _nonce_ we have to get reed of event handlers via HTML attributes and | ||
style attributes in our templates. There is no way to disable `unsafe-eval` since we use it for UI components and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no way to disable
unsafe-eval
since we use it for UI components and
some of the front-end libraries we employ need it (like jQuery).
There 100% is a way to do this, it's just a breaking change. If the work is scheduled, it can be done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I stated in my comment above referring to this exact line
If we are knowingly using vulnerable libraries and the desire is to avoid the vulnerable feature, we should have an active plan to mitigate the risk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getting reed of eval() in Magento front-end is a separate topic, obviously it has to be done but describing how would take another document.
style attributes in our templates. There is no way to disable `unsafe-eval` since we use it for UI components and | ||
some of the front-end libraries we employ need it (like jQuery). | ||
|
||
The work on refactoring templates to remove event handlers and _style_ attributes will be done after CSP is introduced |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The work on refactoring templates to remove event handlers and style attributes will be done after CSP is introduced
gradually
This feels like the wrong order to me. How can we expect merchants to find the time to update their stores for CSP if we, Magento, can't find the time to do it first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good example of this is the @escapeNotVerified
security work done several years ago.
https://magento.stackexchange.com/questions/92963/magento-2-escapenotverified
We still haven't completed this work in core, and it's been > 4 years.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still haven't completed this work in core
Not to take away from your point, we just did it in the last few months. It will be delivered in the next patch releases.
To actually add to your point, it took the work of ALL core teams over 2 months of solid work to properly implement and test those changes. Totally unrealistic effort level for a typical merchant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even with inline styles/JS present in templates we can utilize origin whitelisting for remote resources
Because any work involving security is super important and super high impact, I'm going to list 2 requirements that I think are critical before this plan gets approved:
|
Couple other things:
|
For PWA Studio, I've created magento/pwa-studio#1453 to track our own progress. We don't have legacy code to migrate, so our job here will be much easier. @ericerway The rest of my comment will be about the more general case. I agree with other commenters that a CSP with However, we shouldn't wait to start building the "plumbing" for a CSP as this PR describes. That work has to happen anyway, and we don't need to advertise improved security while we're building the prototype. We should support admin-configurable whitelisting. Whitelisting is less secure than nonce or hash, but as long as Once the plumbing is built, we should create a microsite that demonstrates some core Magento 2 functionality, like a single-product checkout. We should cut scope and functionality until it works with a properly secure CSP (no Then we should iteratively add functionality to the microsite, fixing the script blocks where necessary. Question for @DrewML, @piotrekkaminski, @AlexMaxHorkun , @nathanjosiah and others: Nonce-based whitelisting is expensive and potentially a cache buster. But what about hash-based whitelisting? https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script Hashes can be generated at static deploy time, and they are guaranteed not to allow unexpected code to pass through. |
design-documents/csp.md
Outdated
|
||
CSP mode will be set with a config path not appearing in the admin configuration page so merchants | ||
would have to execute a CLI command in order to change it. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds great:
It would protect the settings against changes via Admin (admins, hacked accounts, admin laptops with malware, ...). Only Dev/DevOps level could change it.
Is there a way to protect the configuration against badly written extensions, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any possible problems with that on Magento Cloud? Related to read-only file system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would need to be written to the env.php file during the build process before deployment completes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the hash comment is very good. can it be pre-generated once during deployment or the inline scripts are dynamic - if the latter it might cause caching issues too? definitely seems like an easier approach than nonces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@piotrekkaminski I've added a bit about hashes
design-documents/csp.md
Outdated
_Magento\Framework\View\Page\Config\Renderer_ will add nonce to all css/js assets being added to a page. With _nonce_ | ||
disabled the presentation class used inside templates will not add nonce when called and _Renderer_ will not do it as well. | ||
|
||
To make it easier for developers and don't force them to include the nonce-helper to all of their blocks it will | ||
be available inside _.phtml_ templates via local `$nonce` variable. | ||
Additional effort will have to go to ensure proper nonce used/regenrated when page cache is enabled. It is possible to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be good to have a more concrete understanding that this can actually be done. As stated by @DrewML Varnish support is integral to the success of this feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanjosiah this helper will be used for hashes/dynamic origin whitelisting depending on the CSP mode selected by merchant so we'd have to have it. There is no conflict between hashes/whitelisted origins and using varnish
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually, Varnish stores the gzipped content in the cache. It means that Varnish will be forced to decompress every cache entry, modify it and compress again for each HTTP request. This will definitely consume more system resources.
Also, we need to support third-party caching providers like Fastly.
Thus, please expand this section with a strategy for third-party providers and another impact on env, setup, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using nonce alongside page cache doesn't seem viable right now, updated the section
design-documents/csp.md
Outdated
There is no way to whitelist an event handler defined via an attribute though (like _onclick_) or styles defined | ||
with _style_ attribute that's why nonce will be | ||
disabled by default and all `unsafe-inline` scripts/styles will be allowed. Merchants who'll be successful in getting | ||
reed of all event handlers/styles defined using HTML attributes will be able to enable _nonce_ via configuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spelling, reed = rid, multiple occurrences in the document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
design-documents/csp.md
Outdated
_Magento\Framework\View\Page\Config\Renderer_ will add nonce to all css/js assets being added to a page. With _nonce_ | ||
disabled the presentation class used inside templates will not add nonce when called and _Renderer_ will not do it as well. | ||
|
||
To make it easier for developers and don't force them to include the nonce-helper to all of their blocks it will | ||
be available inside _.phtml_ templates via local `$nonce` variable. | ||
Additional effort will have to go to ensure proper nonce used/regenrated when page cache is enabled. It is possible to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually, Varnish stores the gzipped content in the cache. It means that Varnish will be forced to decompress every cache entry, modify it and compress again for each HTTP request. This will definitely consume more system resources.
Also, we need to support third-party caching providers like Fastly.
Thus, please expand this section with a strategy for third-party providers and another impact on env, setup, etc.
Fastly responded with a proof of concept of handling nonces through an ESI, however it would be best to use checksums or something similar instead of ESI. I assume the nonce/checksum doesn't have to change until there is a cache update (due to new code/changes being inserted on a page).
|
If I understand correctly what they propose is for Varnish to dynamically replace a certain placeholder for every response but that is not secure since nothing will stop attackers from using the placeholder in their XSS attacks and have Varnish conveniently whitelist their scripts. This problem may be solvable but I think we should proceed without nonce-whitelisting. If we do to decide to include it later it will be just a matter of changing the configuration for merchants. |
Approved with future roadmap to address:
|
Problem
CSP not implemented in Magento
Solution
Implement CSP in Magento in a backward compatible way and allow extension developers to configure it
Requested Reviewers
@joni-jones @paliarush @melnikovi