Skip to main content
Gainsight Inc.

Using PX with Content Security Policy (CSP)

This article describes the steps to allow a Content Security Policy (CSP) to your web application to support Gainsight PX.

Overview

Some web products include a Content-Security-Policy HTTP header in the web application, this helps detect and mitigate certain types of attacks such as XSS and code or data injection by instructing the browser to only execute or render resources from trusted sources. The CSP allows you to create an allowlist of sources of trusted content.

If your web application uses a Content Security Policy (CSP) in HTTP headers or a <META> tag, you must update it to allow Gainsight PX functionality, otherwise, you may see an error similar to the one displayed below in your Google Developer Tools or Firefox Developer Tools.

 Refused to execute aptrinsic.com because it violates the following Content Security Policy directive...

Modify your CSP

In order to take advantage of PX's tracking and engagement experiences, your web application's Content Security Policy (CSP) must include the following directives:

NOTE: If your website already has a CSP, simply add the below to your existing directives. 

connect-src *.aptrinsic.com; script-src *.aptrinsic.com; style-src *.aptrinsic.com 'unsafe-inline' fonts.googleapis.com; img-src *.aptrinsic.com storage.googleapis.com; font-src fonts.gstatic.com; 

Using Gainsight PX With a Strict CSP

Gainsight PX allows the engagements to continue to render with inline styles when the style-src ‘unsafe-inline’ is not specified in your Content Security Policy (CSP). This capability is available for all engagement types in PX. If your security team mandates that the 'unsafe-inline' flag cannot be included in the style-src section of your application's CSP, you must follow additional steps to ensure that the PX engagements are displayed.

Note: When building PX engagements that will be used with a strict CSP and nonce value, it is important that the HTML for the engagement not contain any inline style attributes. Because inline styles will be rejected by your application's CSP, all CSS must be in the CSS tabs in the PX Editor.

The below table represents the HTML with the style attributes embedded for the following typical dialog engagement: 

img1.png

Sample HTML with a number of style attributes, which is not allowed when using a strict CSP that does not style-src unsafe-inline:

img2.png

Sample HTML with all the style= attributes migrated to the CSS tab: 

img3.jpeg

Representation of the HTML migrated to the CSS tab: 

img4.png

Add Nonce Value

To allow the PX engine to include the CSS required to style run-time engagements, a nonce value ( A nonce is a randomly generated token that should be used only one time) needs to be added to the CSP and passed to Gainsight PX during load time. For more information, refer to the Allow Inline Styles using a Nonce section of this article.

The same nonce value is passed to the Gainsight PX tag as a configuration value of the below form:

 cssNonce: 'random nonce value'
 widgetNonce: 'random nonce value'

An example of loading Gainsight PX with a configuration block is:

(function(n, t, a, e, x) {
    let i = "aptrinsic";
    n[i] = n[i] || function() {
            (n[i].q = n[i].q || []).push(arguments)
        },
        n[i].p = e, n[i].c = x;

    let r = t.createElement("script");
    r.async = !0;
    r.src = a + "?a=" + e;

    let c = t.getElementsByTagName("script")[0];
    c.parentNode.insertBefore(r, c);
})
(window, document, "https://web-sdk.aptrinsic.com/api/aptrinsic.js", "AP-XXXXXXXXXXXX-2", {
    cssNonce: "r@nd0m"
    widgetNonce: "r@nd0m"
});

An example of the style-src section of the CSP that matches the above configuration is:

style-src css-cdn.example.com 'nonce-r@nd0m';

 Notes:

  • The cssNonce token is for engagements and widgetNonce is for KC Bot
  • In the CSP, the value is prefixed with “nonce-“, the part after that is the actual nonce, that is passed to PX.
  • The values in the example are static, but in a production environment, they need to be a unique/random/non-guessable value that changes for each page load.
  • Was this article helpful?