Magento 2.3.5 CSP Configuration – Assist with csp_whitelist.xml Setup

cspmagento2magento2.3

I have followed documentation for setting up CSP whitelist using csp_whitelist.xml in a new module, but something is missing/not working as it should.

Issue

I have 100s of style-src 'self' 'report-sample' errors in the console still after applying the module (see below).

Key notes: report_only=0 as I understand should 'enforce' and not just report correct?

The console shows 'report-only'

Image 1 shows 'inline-style' errors for remote locations (from elfsight.com – WhatsApp chat)
Image report information

**Image 2 shows 'inline-styles' for the 'local domain (Magento 2 site)'
enter image description here

module.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
     <module name="Vendor_MagentoCspGloSiteWhitelist" setup_version="1.0.0">
          <sequence>
               <module name="Magento_Csp"/>
          </sequence>
     </module>
</config>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
     <default>
          <csp>
               <mode>
                    <storefront>
                         <report_only>0</report_only>
                         <report_uri>https://vendor.report-uri.com/r/d/csp/enforce</report_uri>
                    </storefront>
                    <admin>
                         <report_only>0</report_only>
                         <report_uri>https://vendor.report-uri.com/r/d/csp/enforce</report_uri>
                    </admin>
               </mode>

          </csp>
     </default>
</config>

csp_whitelist.xml:

<?xml version="1.0"?>
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd">
     <policies>
          <policy id="script-src">
               <values>
                    <value id="sharethis.com" type="host">*.sharethis.com</value>
                    <value id="elfsight.com" type="host">*.elfsight.com</value>
                    <value id="cloudflare" type="host">*.cloudflare.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
                    <value id="google-analytics" type="host">*.google-analytics.com</value>
                    <value id="google" type="host">*.google.com</value>
                    <value id="gstatic" type="host">*.gstatic.com</value>
                    <value id="fontawesome" type="host">*.fontawesome.com</value>
               </values>
          </policy>
          <policy id="style-src">
               <values>
                    <value id="elfsight.com" type="host">*.elfsight.com</value>
                    <value id="cloudflare" type="host">*.cloudflare.com</value>
                    <value id="googleapis" type="host">*.googleapis.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
                    <value id="gstatic" type="host">*.gstatic.com</value>
                    <value id="fontawesome" type="host">*.fontawesome.com</value>
               </values>
          </policy>
          <policy id="img-src">
               <values>
                    <value id="cloudflare" type="host">*.cloudflare.com</value>
                    <value id="googleadservices" type="host">*.googleadservices.com</value>
                    <value id="google-analytics" type="host">*.google-analytics.com</value>
                    <value id="paypal" type="host">*.paypal.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
                    <value id="data" type="host">'self' data:</value>
               </values>
          </policy>
          <policy id="connect-src">
               <values>
                    <value id="sharethis.com" type="host">*.sharethis.com</value>
                    <value id="elfsight.com" type="host">*.elfsight.com</value>
                    <value id="cloudflare" type="host">*.cloudflare.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
                    <value id="paypal" type="host">*.paypal.com</value>
               </values>
          </policy>
          <policy id="font-src">
               <values>
                    <value id="cloudflare" type="host">*.cloudflare.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
                    <value id="gstatic" type="host">*.gstatic.com</value>
                    <value id="typekit" type="host">*.typekit.net</value>
                    <value id="trustedshops" type="host">*.trustedshops.com</value>
                    <value id="googleapis" type="host">*.googleapis.com</value>
               </values>
          </policy>

          <policy id="frame-src">
               <values>
                    <value id="gstatic" type="host">*.gstatic.com</value>
                    <value id="twitter.com" type="host">*.twitter.com</value>
               </values>
          </policy>

          <policy id="form-action">
               <values>
                    <value id="twitter.com" type="host">*.twitter.com</value>
               </values>
          </policy>
     </policies>
</csp_whitelist>

Questions:

  • What am I missing here, as inline styles (local and elfsight.com stuff are reported)
  • What is 'report-sample' here? I do not see any information anywhere
  • All the local inline-style errors, what do I do here ? The Theme we use are using so many inline styles (calculated from Javascript).
  • Are there any 'default' values that does not apply if you create a custom csp_whitelist.xml?
  • How do I even confirm if it is using my csp_whitelist.xml, as mentioned report-only=0 or report-only=1 gives the same [Report Only] message in the console, and it doesn't feel like report-only=0 enforces anything.

Best Answer

So, it turns out it was a Chrome extension installed a few weeks ago (which I kind of have forgotten about).

The name is 'Content Security Policy (CSP) Generator', which never indicated where it 'generates' the entries, but this extension reports all items, even if it works and appends 'report-sample' which completely confused me as to origin of this.

Disabling the extension gave me a 100% clearer picture of which items didn't have CSP entries.

For reference, a working setup I created of config and whitelist below.

config.xml - Here is how to use report_only=0 (enforce), but more importantly, fix for frame-ancestors which does not allow unsafe-inline in browsers (as of November 2021).

  • frame-ancestors fix is only currently applied in 2.4-develop branch.
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
     <default>
          <csp>
               <policies>
                    <storefront>
                         <frame-ancestors>
                              <inline>0</inline>
                         </frame-ancestors>
                    </storefront>
                    <admin>
                         <frame-ancestors>
                              <inline>0</inline>
                         </frame-ancestors>
                    </admin>
               </policies>
               <mode>
                    <storefront>
                         <report_only>0</report_only>
                         <report_uri>https://site.report-uri.com/r/d/csp/enforce</report_uri>
                    </storefront>
                    <admin>
                         <report_only>0</report_only>
                         <report_uri>https://site.report-uri.com/r/d/csp/enforce</report_uri>
                    </admin>
               </mode>

          </csp>
     </default>
</config>

csp_whitelist.xml

  • I decided to name (id) them like this :wildcard., because there are some rare instances where non-wildcard domains (like elfsight.com) rule do not work with them, so for instance 'img-src' I have two entries : 'elfsight.com' and 'wildcard.elfsight.com', two rules needed.
<?xml version="1.0"?>
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd">
     <policies>
          <policy id="script-src">
               <values>
                    <value id="wildcard.sharethis.com" type="host">*.sharethis.com</value>
                    <value id="wildcard.elfsight.com" type="host">*.elfsight.com</value>
                    <value id="wildcard.cloudflare" type="host">*.cloudflare.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
                    <value id="wildcard.google-analytics" type="host">*.google-analytics.com</value>
                    <value id="wildcard.google" type="host">*.google.com</value>
                    <value id="wildcard.gstatic" type="host">*.gstatic.com</value>
                    <value id="wildcard.fontawesome" type="host">*.fontawesome.com</value>
               </values>
          </policy>
          <policy id="style-src">
               <values>
                    <value id="wildcard.elfsight.com" type="host">*.elfsight.com</value>
                    <value id="wildcard.cloudflare" type="host">*.cloudflare.com</value>
                    <value id="wildcard.googleapis" type="host">*.googleapis.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
                    <value id="wildcard.gstatic" type="host">*.gstatic.com</value>
                    <value id="wildcard.fontawesome" type="host">*.fontawesome.com</value>
               </values>
          </policy>
          <policy id="img-src">
               <values>
                    <value id="elfsight.com" type="host">elfsight.com</value>
                    <value id="wildcard.elfsight.com" type="host">*.elfsight.com</value>
                    <value id="wildcard.cloudflare" type="host">*.cloudflare.com</value>
                    <value id="wildcard.googleadservices" type="host">*.googleadservices.com</value>
                    <value id="wildcard.google-analytics" type="host">*.google-analytics.com</value>
                    <value id="wildcard.paypal" type="host">*.paypal.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
                    <value id="wildcard.data" type="host">'self' data:</value>
               </values>
          </policy>
          <policy id="connect-src">
               <values>
                    <value id="wildcard.sharethis.com" type="host">*.sharethis.com</value>
                    <value id="wildcard.elfsight.com" type="host">*.elfsight.com</value>
                    <value id="wildcard.cloudflare" type="host">*.cloudflare.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
                    <value id="wildcard.paypal" type="host">*.paypal.com</value>
               </values>
          </policy>
          <policy id="font-src">
               <values>
                    <value id="wildcard.cloudflare" type="host">*.cloudflare.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
                    <value id="wildcard.gstatic" type="host">*.gstatic.com</value>
                    <value id="wildcard.typekit" type="host">*.typekit.net</value>
                    <value id="wildcard.trustedshops" type="host">*.trustedshops.com</value>
                    <value id="wildcard.googleapis" type="host">*.googleapis.com</value>
               </values>
          </policy>

          <policy id="frame-src">
               <values>
                    <value id="wildcard.google" type="host">*.google.com</value>
                    <value id="wildcard.gstatic" type="host">*.gstatic.com</value>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
               </values>
          </policy>

          <policy id="form-action">
               <values>
                    <value id="wildcard.twitter.com" type="host">*.twitter.com</value>
               </values>
          </policy>
     </policies>
</csp_whitelist>
Related Topic