Overview

With the release of version 2.3.5, Magento has added another tool to combat Cross-Site Scripting (XSS) attacks with the built-in Magento_Csp module. This module adds support for Content Security Policy HTTP headers, and include policies such as:

  • Any resource, such as .js, .css, .jpg, or .ttf files, can only be loaded from the store’s domain
  • Iframes can only include pages from the store itself
  • AJAX requests can only be sent to the store
  • Forms can only be sent to the store

Policy violations are either reported or blocked, based on the configuration of vendor/magento/module-csp/etc/config.xml. In Magento 2.3.5, violations are only reported by default, however, this might change with a future release, which can block any external sources not whitelisted.

CSP is supported by all modern browsers, and violations are logged into console regardless of Module_Csp configuration:

Content Security Policy report

So how can you whitelist the module’s external sources to satisfy CSP?

The csp_whitelist.xml configuration file

Magento_Csp introduces csp_whitelist.xml file, which developers can use to add resource origins to request headers. All listed origins will form a whitelist called when a page loads, calls to any origins not in this list (or not from the store’s domain) are treated as CSP violations.

  • This file is placed under <vendor>/<module>/etc/csp_whitelist.xml
  • Based on schema Magento_Csp/etc/csp_whitelist.xsd
  • Structure is as follow:
<policies>
<policy id="{policy 1 directive}">
        		<values>
            		<value id="{value 1 id}" type="{value 1 type}">{value 1}</value>
        		</values>
    	</policy>
    	<policy id="{policy 2 directive}">
        		<values>
            		<value id="{value 1 id}" type="{value 1 type}">{value 1}</value>
<value id=”{value 2 id}" type="{value 2 type}">{value 2}</value>
...
        		</values>
    	</policy>
    	...
</policies>

Directives

The most common directives include:

  • script-src : sources for JavaScript
  • img-src : sources of images and favicons
  • style-src : sources for stylesheets
  • object-src : sources for the <object>, <embed>, and <applet> elements
  • media-src: sources for loading media
  • connect-src : URLs which can be loaded using script interfaces
  • default-src: fallback for the other fetch directives (script, img, style, object, media, connect, etc.). It’s recommended to include a default-src directive in case fetch directives are used in the module
  • base-uri : URLs which can be used in a document's <base> element
  • form-action : URLs which can be used as the target of a form submissions from a given context

Each directive can be referred in the configuration once. For a full list of accepted directives, visit Magento dev doc.

Value Id

User-defined.

Type

Accepted types are “host” for a source host, “hash” or a hash string

Value

String type. If type is host, then only the domain is required (protocol and path not needed). Wildcard domains are accepted.

Configuration Sample

<?xml version="1.0" encoding="UTF-8"?>
<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="font-src">
        			<values>
            			<value id="gstatic" type="host">fonts.gstatic.com</value>
        			</values>
    	</policy>
    	<policy id="style-src">
        		<values>
            		<value id="google_stype" type="host">fonts.googleapis.com/</value>
        		</values>
    	</policy>
    	<policy id="default-src">
        		<values>
          		  	<value id="google_fallback" type="host">*.googleapis.com</value>
        		</values>
    	</policy>
    	<policy id="form-action">
        		<values>
            		<value id="google_form" type="host">*.google.com</value>
        		</values>
    	</policy>
	</policies>
</csp_whitelist>

This file defines:

  • A font source from fonts.gstatic.com
  • A stylesheet source from fonts.googleapis.com
  • A fetch default source from *.googleapis.com
  • Valid form action URL for *.google.com

Finally, run code compilation command: php bin/magento setup:di:compile to update the whitelist after creation/updates.

Whitelist inline scripts or styles

Whitelisting an inline script or style is possible via Magento\Csp\Api\InlineUtilInterface class using renderTag() method.

Coding Sample

class renderInline
{
	/**
 	* @var \Magento\Csp\Api\InlineUtilInterface
 	*/
	private $inlineUltiInterface;

	//...

	/**
	* string $htmlContent
	* string $inlineContent
	public function renderSomeHtml($htmlContent, $inlineContent)
{
    		$htmlContent .= $this->inlineUltiInterface>renderTag(
        			'script',
        			['type' => 'text/javascript'],
        			$inlineContent
    		);
    		return $htmlContent;
	}
}

In this sample, renderTag() will scan the $inlineContent for any hosts and add those hosts to the request header when rendering $htmlContent.

FAQ

  1. How to check which resource origins are whitelisted? Using developer tools on your browser, check the value of Content-Security-Policy and/or Content-Security-Policy-Report-Only in Response headers when a page loads.
  2. Can one module’s csp_whitelist.xml be used to whitelist sources from other modules? Yes, whitelist xml from all enabled modules are used to add resource origins to the request header. However, for seamless development, it’s recommended that each module whitelist its own external sources.
  3. How to add Data URIs/Data URLs (for example data:image) as resource origin? They can be added using ‘data:’ as the source value. However, attackers can inject arbitrary data: URIs, so this source must not be used for script sources.
  4. Can value id be duplicated in different csp_whitelist.xml files? Yes, value id doesn’t have to be unique. Both values will still be loaded in case of duplication.

If you have any questions, please let us know in the comment section below. Thanks for reading!