Magento 2.3.5-p1 CSP font-src self unsafe-inline

Magento 2.3.5 p1 added a new module module-csp ( Magento_Csp ) which supports Content Security Policies ( CSP ) headers and provides ways to configure them. The policies can be configured for backend and frontend areas both.

Content Security Policies ( CSP ) has two modes – report-only and restrict. In Magento 2.3.5 p1, the default mode is report-only which is shows the policy violations in the browser's console. You can configure these csp for all third party loaded content as per your custom modules and theme.

I was able to solve all the policy errors for my site by creating a custom module.

app/code/Namespace/Csp/registration.php

<?php
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Namespace_Csp',
        __DIR__
    );

app/code/Namespace/Csp/etc/module.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Namespace_Csp" setup_version="1.0.0" />
</config>

app/code/Namespace/Csp/etc/config.xml

<?xml version="1.0"?>
<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_uri>https://www.example.com/</report_uri>
                </storefront>
                <admin>
                    <report_uri>https://www.example.com/</report_uri>
                </admin>
            </mode>
            
        </csp>
    </default>
</config>

app/code/Namespace/Csp/etc/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="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="twimg" type="host">*.twimg.com</value>
                <value id="gstatic" type="host">*.gstatic.com</value>
                <value id="trustedshops" type="host">*.trustedshops.com</value>
                <value id="usercentrics" type="host">*.usercentrics.eu</value>
                <value id="fontawesome" type="host">*.fontawesome.com</value>
            </values>
        </policy>
        <policy id="style-src">
            <values>
                <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="twimg" type="host">*.twimg.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="usercentrics" type="host">*.usercentrics.eu</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="klarna-base" type="host">*.klarna.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="twimg" type="host">*.twimg.com</value>
                <value id="vimeocdn" type="host">*.vimeocdn.com</value>
                <value id="youtube-img" type="host">*.ytimg.com</value>
                <value id="data" type="host">'self' data:</value>
                <value id="lightemporium" type="host">*.lightemporium.com</value>                
                <value id="usercentrics" type="host">*.usercentrics.eu</value>
            </values>
        </policy>
        <policy id="connect-src">
            <values>
                <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>
                <value id="twimg" type="host">*.twimg.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="twimg" type="host">*.twimg.com</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="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>

Add your thirdparty urls/domains to csp_whitelist.xml. All suggestions are most welcome


At the end of the console report, it says:

"...was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header."

This is not saying that the the domain values for each of the listed policies are not whitelisted, they are by default (this error made me believe they weren't until I really looked at it closer). It's saying that there is no report-uri directive.

From the devdocs, it says:

Regardless of restrict or report-only mode, CSP violations may be reported to an endpoint for collection. The URL to use for reporting by browsers can be configured in your custom module’s config.xml file:

<?xml version="1.0"?>
<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_uri>http://csp-reporting-service.com/my-project/endpoint</report_uri>
                </storefront>
                <admin>
                    <report_uri>http://csp-reporting-service.com/my-project/endpoint</report_uri>
                </admin>
            </mode>
        </csp>
    </default>
</config>

By default, CSP sends errors to the browser console, but can be configured to collect error logs by HTTP request. In addition, there are a number of third-party services that you can use to monitor, collect, and report CSP violations. So, either configure it to be reported to the error logs by https request, or create a custom module and configure the report_uri directive with the CSP reporting service of your liking. https://devdocs.magento.com/security/content-security-policy-overview.html


This worked for me:

https://maxchadwick.xyz/blog/magento-disable-csp

How To Disable Content Security Policy (CSP) The best way to disable Content Security Policy is to disable the Magento_Csp module:

php bin/magento module:disable Magento_Csp

Please read that article for more details