Configuring Content Security Policy Headers

Beta Feature

Modern browsers use Content Security Policy HTTP response headers to enhance web pages’ security to mitigate certain types of attacks (like Cross-Site Scripting or data injection). You can enable CSP on Liferay to send the configured headers on each HTTP request.

CSP policies have many options. It is best to understand your users’ needs and come up with a policy to suit their requirements. After enabling CSP headers, they’re enforced by the browsers. Visit the links below to learn more about how browsers handle CSP headers:

Warning

This feature is currently behind a beta feature flag. See Beta Feature Flags for more information. Configuring an unsupported content security policy can cause your instance to malfunction.

Content Security Policy Directives and Values

Content Security Policies take the form of key-value pairs. The keys are directives, and they can have values. Using directives and values, you can form a robust policy to protect web applications against a variety of threats.

Directives: Directives specify the resources (scripts, stylesheets, images, etc.) a browser can load or execute on a web page. Below are examples of some commonly used directives, and the most restrictive values supported by Liferay.

DirectiveMinimum Supported ValueDescription
default-srcN/ASpecifies the default source for content types not explicitly defined by other directives.
base-uriN/ASpecifies the base URL for resolving relative URLs.
connect-srcselfSpecifies the sources to which you can make network requests.
frame-ancestorsnoneSpecifies which parent pages can embed resources in frames, IFrames, or other embed elements.
frame-srcselfSpecifies the domains from where you can embed pages or applications into a frame or IFrame.
img-srcselfSpecifies the sources from where you can load images.
script-srcself unsafe-inlineSpecifies the sources from where you can load and execute JavaScript.
script-src-attrnoneSpecifies the sources from where you can load inline script event handlers like onClick.
style-srcself unsafe-inlineSpecifies the sources from where you can load stylesheets. Acts as the default for style-src-attr and style-src-elem if they’re not defined.
style-src-attrunsafe-inlineSpecifies the valid sources for inline styles applied to DOM elements in your stylesheets.
style-src-elemself unsafe-inlineSpecifies the valid sources for style elements.

Values: Values specify the approved origins to load resources from. Below are examples of some commonly used values. In addition to these, you can also specify URLs.

ValueDescription
selfAllows loading and execution of resources from the same origin.
unsafe-evalAllows execution of code generated by eval() and other unsafe methods.
unsafe-inlineAllows the inclusion of inline stylesheets, scripts, inline event handlers, etc.
[$NONCE$]Allows execution of scripts or loading of stylesheets with a specific nonce value generated by the server.
strict-dynamicAllows execution of scripts from trusted sources. Scripts included by loaders from a trusted script are not blocked.
noneBlocks execution of the specified directive from all sources.

It’s important to note that while unsafe-eval and unsafe-inline provide flexibility in terms of code execution and styling, they come with increased security risks.

In general, you should set your CSP headers to be as restrictive as your required sources allow to minimize the risk of possible security threats. However, Liferay currently cannot support a fully unsafe- free CSP due to existing limitations. See Current Limitations of CSP for more information.

Warning

While strict-dynamic simplifies CSP configuration and reduces the need for nonce propagation, it may enlarge the attack surface by allowing any script loaded by trusted scripts to execute.

Alternatively, you can send nonces from the server to the client, ensuring that dynamically loaded scripts have the necessary nonce attribute for compliance with CSP. This approach involves proprietary mechanisms, managed by Liferay, to propagate nonces from the server to the client.

This approach provides more granular control over script loading and may be preferable in scenarios where strict control over script execution is essential. However, it requires proprietary mechanisms for nonce propagation, which may be more complex.

The choice between strict-dynamic and nonce propagation depends on factors such as the specific threat model, risk tolerance, and operational requirements. Consider the pros and cons before implementing it in your CSP.

Configuring a Sample Content Security Policy

  1. Open the Global Menu (Global Menu) and navigate to Control PanelInstance SettingsSecurityContent Security Policy.

    Configuring a content security policy.

  2. To enable CSP headers, check the Enabled checkbox. You can enter your policy in the Content Security Policy input field and specify a number of paths to exclude (see below).

  3. Enter the following policy in the Content Security Policy input field.

    default-src 'self'; script-src 'self' https://trusted-cdn.example.com '[$NONCE$]'; style-src 'self' https://trusted-cdn.example.com '[$NONCE$]' base-uri 'self';
    

This sample content security policy allows resources to load only from the same origin self and from the trusted content delivery network https://trusted-cdn.example.com. It also includes the nonce '[$NONCE$]' for scripts and stylesheets to secure their integrity and prevent unauthorized script execution. The base-url 'self' value instructs the browser to allow loading resources only from the same origin as the document.

  1. Click Update.

Content Security Policy: Specify the content security policy to enforce. The value entered here appears as the value for the Content-Security-Policy HTTP header. You can add a nonce by using the placeholder '[$NONCE$]' in your content security policy. The placeholder is replaced with a generated nonce for the tags you specify.

Excluded Paths: Paths that start with the value added here are excluded from the content security policy. You can add multiple paths to exclude by clicking the Add Setting icon button or remove them using the Remove Setting icon button.

Note

CSP configuration is available at all scopes. For the system scope, go to Control PanelSystem SettingsSecurityContent Security Policy. For the site scope, open the site menu and go to ConfigurationSite SettingsSecurityContent Security Policy.

Current CSP Limitations and Recommendations

CSP headers are a beta feature with these limitations:

  • Your script-src directive must have the unsafe-inline value defined to support CKEditor 4. CKEditor is the only supported WYSIWYG editor.

  • Your style-src directive must have the unsafe-inline value, because Liferay both has inline style attributes and adds stylesheets to the <head> tag using scripts.

In a future version of Liferay, CKEditor 5 and the removal of inline styles will address these limitations.

Note

Content Security Policies work best with SPA disabled. To disable it, add javascript.single.page.application.enabled=false to your portal-ext.properties file. Site level configuration panel and common pages (such as the 404 page) belong to the instance, so they use the instance level CSP headers.

Because of these limitations, you cannot fully restrict these attributes to the (otherwise minimal) self attribute.

However, you can split your style-src directive into the style-src-attr and style-src-elem directives to further minimize risk. Then, set the style-src-elem directive using nonce values instead, for any style elements you need.

Using specific nonce values for your styles, you can set these more restrictive directives like this:

style-src-attr 'unsafe-inline';
style-src-elem '[$NONCE$]';

So the most restrictive supported policy is:

script-src '[$NONCE$]';
script-src-attr 'none';
style-src-elem '[$NONCE$]';
style-src-attr 'unsafe-inline';
connect-src 'self';
img-src 'self';
frame-ancestors 'none';
frame-src 'self';

This strict configuration is recommended where possible for your site. If a page on your site does not work with your configuration (for example, because the page uses CKEditor 4), you can exclude those pages from the path by adding them under Excluded Paths.

Use the Excluded Paths repeatable field to exclude any pages that don't work with your policy.

Extra CSP Limitations Before Liferay 2025.Q1+

These extra limitations are in place for Liferay versions before 2025.Q1:

  • Your script-src directive must have the unsafe-eval value defined for Liferay to properly bundle code.

  • Your script-src-attr directive must have the unsafe-inline value for inline event listeners within HTML elements within Liferay.

Capabilities

Product

Education

Contact Us

Connect

Powered by Liferay
© 2024 Liferay Inc. All Rights Reserved • Privacy Policy