Content Security Policy

Background

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft, to site defacement, to malware distribution.

 

Who needed it?

Administrators who care about security.

 

What problem does it solve?

With a strict policy an added layer of security can be provided on the client side which protects against XSS and data injection attacks. The existence of the Content Security Policy header is often a security audit requirement as well.

 

How can it be used by the user or developer?

The users will receive the Content Security Policy response header on each HTTP request which will be interpreted and enforced by their browsers.

Features

Our Content Security Policy implementation does two things right now:

  1. Adds Content-Security-Policy HTTP header to each response. The value of this header can be configured by Administrators.

  2. Adds a random generated nonce value to each link, script and style tags according to the configured Content-Security-Policy HTTP header. The nonce value is freshly generated on each request and its value can be used in the policy.

 

Steps

Go to “System/Instance/Site Settings > Security > Content Security Policy”. Here the Administrators can enable or disable this feature, specify the policy and add URI paths which they want to be excluded from Content Security Policy modifications.

In the Content Security Policy field if the user writes [$NONCE$] it will be replaced by the generated value on each request.

Right now CSP works best with single-page-applications (a.k.a SPA) disabled which can be done by adding javascript.single.page.application.enabled=false to portal-ext.properties.

With SPA disabled, for example, the following policy can be used: default-src 'self'; base-uri 'self' 'strict-dynamic'; connect-src 'self'; img-src data: 'self' w3.org/svg/2000; script-src 'self' 'strict-dynamic' '[$NONCE$]' 'unsafe-eval'; script-src-attr 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';

 

Code

All relevant code is under “modules > apps > portal-security > portal-security-content-security-policy” package.

  • ContentSecurityPolicyConfiguration.java: Configuration class for the module.

  • ContentSecurityPolicyConstants.java: CSP related constants are stored here.

  • ContentSecurityPolicyFilter.java: This class does the main functionality. It’s a Servlet Filter that adds the Content-Security-Policy header to the response and intercepts the response body and rewrites all link, script and style tag to contain a nonce.

Limitations

Due to webpack bundling settings liferay.js has the following line Function(\"return this\")() which won’t work because Refused to evaluate a string as JavaScript unless we add 'unsafe-eval' to our policy. How to remove eval and Function constructor from webpack build to avoid CSP issues · Issue #6461 · webpack/webpack

We have a lot of style attributes inside HTML elements as well as some style additions to head part by scripts. For this reason we need to enable 'unsafe-inline' for styles.

Sometimes we use inline event listeners which are treated as scripts from Content Security Policy point of view so to overcome this we need to add script-src-attr 'self' 'unsafe-inline'; to our policy.

CKEditor is causing issues with the provided CSP rule but only on pages which would use it. Either the rule can be changed to script-src ‘self' 'unsafe-inline' 'unsafe-eval'; or add /group/guest/~/control_panel/manage as an excluded path but by default we wouldn’t recommend any of them. Since 7.3 CKEditor is the only supported WYSIWYG editor but Liferay is using CKEditor 4 which cannot be used without unsafe-inline (https://csplite.com/csp/test347/#nonce_dynamic).

Important notes

Site level configuration panel and common pages (such as 404 page) belong to the instance so an instance level CSP header will be used.

If you remove exclusion of /combo from config you can specify a stricter CSP such as: default-src 'self'; base-uri 'self' 'strict-dynamic'; connect-src 'self'; img-src data: 'self' w3.org/svg/2000; script-src 'self' 'strict-dynamic' '[$NONCE$]' 'unsafe-eval'; script-src-attr 'self' 'unsafe-inline'; style-src 'self' 'strict-dynamic' '[$NONCE$]'; style-src-attr 'self' 'unsafe-inline'; however bear in mind resources at /combo belong to the instance so instance CSP config values will be used.

 

Future plans

This update is only the first part of the CSP implementation, we are going to work on the next components in the near future:

  1. Unsafe inline

  2. Unsafe hashes

  3. Unsafe expressions

  4. Managing the Content-Security-Policy-Report-Only header with configuration

Blogs

Where is this setting located: “System/Instance/Site Settings > Security > Content Security Policy” I've tried searching under System Settings, Instance Settings and Site Security and there's nothing coming up. Has it been moved?

Dear Adrian! First of all thanks for your question! This feauture was released under a Beta feature flag in the U82 release. Which means in order to use this feature at first you need to go to :"Control Panel > Instance settings > Feature Flags > Beta > and search for CSP" > enable it". After enabling it, it will be shown at “System/Instance/Site Settings > Security > Content Security Policy” . I hope I could help!

Hi, there are new developements going on actually on CSP or the activities on CSP at the moment are stuck? The ticket to follow activities on CSP is always LPS-134060 or there is a new ticket to watch?