How to Fix Magento 2.3.5 Content Security Warnings

To prevent Cross Site Scripting (XSS) and other related attacks Magento 2.3.5 has added a new module, Magento_Csp, called Content Security Policies. This module is Magento’s effort to improve security and keep your Magento site safe. Content Security Policies (CSP) are a powerful tool to mitigate against Cross Site Scripting (XSS) and attacks such as […]

By James Cowie

To prevent Cross Site Scripting (XSS) and other related attacks Magento 2.3.5 has added a new module, Magento_Csp, called Content Security Policies. This module is Magento’s effort to improve security and keep your Magento site safe.

Content Security Policies (CSP) are a powerful tool to mitigate against Cross Site Scripting (XSS) and attacks such as card skimmers, session hijacking, clickjacking, and more. Web servers send CSPs in response HTTP headers (namely Content-Security-Policy and Content-Security-Policy-Report-Only) to browsers that whitelist the origins of scripts, styles, and other resources. Together, CSPs and built-in browser features help prevent:

  • Loading a malicious script from an attacker’s website
  • A malicious inline script from sending credit card info to an attacker’s website
  • Loading a malicious style that will make users click on an element that wasn’t supposed to be on a page

See Content Security Policy (CSP) and Content-Security-Policy to learn more about CSP and each individual policy.

If you are working on a 2.3.5 project then I am sure you see a lot of these lines in your web developer console:

The CSP module operates in 2 modes:

  • Report only mode – This does what it says, It reports in the console the potential violations, Just as in the screen above.
  • Restrict mode – In this mode, Magento will enforce the policies and block the loading of the resources.

There are some threads that at the moment don’t consider CSP to be mature enough or the correct approach. I’m still on the fence with the implementation but anything that can be done to make Magento safer is a big tick in my book.

How to resolve Content Security Policies warnings

So you’re working on a Magento 2.3.5 project and you have a console full of red lines, What do you do? Well, the first thing we do is create a new module. For this post, we will call it Shero_Csp and it will live in the usual app/code folder. The module isn’t going to do anything but store our configuration file that Magento reads to whitelist resources.

If you’re using PHPStorm make sure to have the Magento plugin installed because then you can just right click and create a new Magento 2 module. This then creates the composer.json, registration.php, and etc/module.xml files all with the correct namespaces. The first file we need to add is etc/config.xml This file will be read and offers the ability to configure a CSP Endpoint which is a very powerful tool to report on all potential violations.



    
        
            
                
                    https://www.example.com/
                
                
                    https://www.example.com/
                
            

        
    

The structure is very simple. We are just setting up 2 report_uri nodes for the frontend and the admin. We will touch on this more in future articles to show what tools are available and what additional protection they offer. Next is the creation of etc/csp_whitelist.xml this is the main file that will hold the configurations to whitelist resources based on the different CSP policies.



    
        
            
                *.cloudflare.com
                *.twitter.com
                *.fontawesome.com
            
        
        
            
                *.cloudflare.com
                *.fontawesome.com
                *.bootstrapcdn.com
            
        
        
            
                *.cloudflare.com
            
        
        
            
                *.cloudflare.com
            
        
        
            
                *.cloudflare.com
                *.bootstrapcdn.com
            
        
    

As you can see, This file isn’t overly complex and it just contains the different policies that the CSP supports. When we need to whitelist a resource we can add to this file under the correct policy.

Let’s use a real example.

(index):1 [Report Only] Refused to load the font 'data:font/woff2;base64,d09GMgABAAAAAWmQAA0AAAAEOOAAAWkyAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoV+G4PBSByBohwGYACB50AKh9QwhrRHC6dIAAE2AiQDzwwEIAWLKgeBxlJbStSz31Jku3vgw5MvKUoGo86auG2oGCSoUECjNsdo+zg4ETLB+jKl8vy/jO0+3B9jUioeoiodY9QDGw7Ry6qPr2BxbPuHo0rPbcvJuiJs2f/////////////////////+5T9hm/3/JrNvjpyEcIXbgEBEpbS1SrXudjUhoPOBMc3yIkopKV1FGKgGinUpaSV5KsOMTRxJkLGa6KnM2vliWktunmEmuES5cCQjvVo5SinrTQiqlWLlDQJhsTW8g1Nm02k9VVGNABUBy0G30yGxHY5kQ+VkXyinnFRyL50cggyH6rgNC556Fl4GmSqUV/dopGZq0Uxq6k0OH4j7xM+jBj1yvVUTFfDUmoeHJ1AVoRkp...KvQrzk+cqeUYNgybpbq+terWMcLKormtG+cQFCMIJiOEFSNMNyHsEjSusyJsK7UTYuRHewRxXsqR00QfWqa5IGQI5waR5OUX6l5wzUugEhTCjjQipj9ytBiOQU2uSVERPKuJBKG+vyKgCZkEob6/KqABEmlHEhlTbW5dUAXh+F3QNAhAllXEhtrMvrAgz1QmljXV4fQIQJNdbtF2H6M/Q4cbb6vyMgwoQyLqTSZvaJMQYXeyURJqN3lnnKPt/NhN11zrvo7U4FnfedJ5jSM7LuerUCwAPWTh0WoYyLpX9ZngFMRsW4kEob6+aRupchlHEhlTbW5fUAIkwo45NPnim0sW7xoz0qTEbFuJBKG+vyigARJpRxIZU21uWVACJMKONCnpChbvaZfgT/JCS0cf+Pglo9f5tH1pBH/4RLYo+YmPFNjhdhdA1e/s+SoaXsj7ua+UOgRrlunpFnoqLgzFFeUP05uKF7Fyu5NFJw28FQRLENnfK3NhqOPAMAAA==' because it violates the following Content Security Policy directive: "font-src 'self' 'unsafe-inline'".

This is one of the resources that violates the CSP policy. We can tell it comes from the Magento module and not the browser because of the [Report Only] and what this is saying is that it’s refusing to load the font because of the font-src policy. 

Heading back into etc/csp_whitelist.xml lets whitelist the data: attribute under font-src:


  
    'self' data:
    'unsafe-inline' data:
  

What we are saying here is that anything loaded via data: will pass the CSP policy.

Another example is loading custom CSS from Bootstrap CDN.


  
    *.bootstrapcdn.com
  

This time we have to update the style-src policy and we add in a new value with a descriptive ID and the domain to whitelist. Try and be as specific as possible but don’t go over the top. Using wildcards on the main domain is acceptable for me and still offers the protection that the CSP tries to provide. 

Just remember to test this locally and on QA/UAT so that you have a complete understanding of what content is needed to be whitelisted and then once prepared, enable restrict mode. The additional level of security this offers to stop some of the malicious injected JS that skims cards and steals data etc would then be blocked from loading making all the stores more secure.

External reporting 

It’s great that the console is logging the reports in report-only mode, but as an added security measure it would be ideal to see in a system when a violation occurs. If for some reason some “bad” javascript got injected into the site then it should trip up the content security policy and using the XML node report_uri it’s possible to post the violation over to a service. 

There are many services out there but the one we have used the most is https://report-uri.io it has a free tier that’s locked to 10,000 reports per month. Even when upgraded to the paid for service it offers the maximum amount of coverage for security. 

To enable this feature in config.xml that we created update the XML to look like:



    
        
            
                
        https://report-uri.com/r/d/csp/reportOnly
                    1
                
                
                    https://report-uri.com/r/d/csp/reportOnly
                    1
                
            
        
    

Once you create an account on report-uri you will be given the option to configure your endpoint and this is the value that you need to enter into report_uri field. 

Now any time a content security policy is violated you will be able to see exactly what violation occurred and act upon it. 

This level of security really helps make sure that no JS can be executed should it be injected and even though we run WAF (web application firewalls) and have advanced monitoring, having another line of defense to protect client sites really does help ensure that malicious code is as hard to inject as possible.