Content Security Policy (CSP)

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.

Content security policies act as whitelists for what domains and HTML elements are allowed to:

  • Execute scripts (script-src-elem, script-src, default-src)
  • Load styles (style-src-elem & style-src)
  • Perform network requests (connect-src)
  • Load images (img-src)

If a CSP is present in a HTML page, network requests for scripts, styles, images, and network requests to domains are automatically blocked if not whitelisted. If this happens, a console error is emitted on the page specifying which domain was blocked and which rule was violated, along with suggestions for possible fixes to allow the content. This is important to test in a staging environment, especially for connect-src as this can vary depending on the region / environment that the bot is in.

If enabling CSP and the web server is configured to return the Content-Security-Policy for inline styles, a pinned version of messenger will be required to ensure that the secure hash algorithm (SHA) does not change and therefore break the content policy as new versions of the messenger are released.

Version Pinning

If using version pinning - the following script URLs can be used within the client script:

  • For SBRegion eu-1: Use //lightning.production.helium.servismatrixcdn.com/v2/<version_number>/bundle-messenger.js
  • For SBRegion us1: Use //lightning.us1.helium.servismatrixcdn.com/v2/<version_number>/bundle-messenger.js

Inline Styles

If setting a CSP of style-src 'self' a SHA must be provided as part of the CSP content as follows

  <meta
    http-equiv="Content-Security-Policy"
    content="
      style-src 'self' fonts.googleapis.com cdn.jsdelivr.net cdn.datatables.net *.servismatrixcdn.com *.servismatrix.com sborg-ENVIRONMENT-ORGANIZATION.s3.amazonaws.com cognito-identity.eu-west-1.amazonaws.com 'sha256-<value_here>';
    "
  />

Your account manager should be able to provide information about the values for ENVIRONMENT & ORGANIZATION

Regular (non lazy-loaded) messenger bundle

This bundle relies on the execution of two scripts:

  1. servisbot-utils.js
  2. bundle-messenger.js

style-src 'unsafe-inline' allows all inline styles - this setting is typically not recommended, but is required as the messenger uses inline styles. If using unsafe-inline is not possible, the messenger version will need to be pinned, and a messenger hash will need to be used (See ‘Version Pinning’ above).

When using the regular (non lazy-loaded) bundle, here is an example CSP:

<head>
  <meta
    http-equiv="Content-Security-Policy"
    content="
      default-src 'none';
      script-src 'self';
      img-src: 'self' data:,
      style-src 'self' 'unsafe-inline' https://lightning.production.helium.servismatrixcdn.com/v2/latest/bundle-messenger.js;
      script-src-elem 'self' https://lightning.production.helium.servismatrixcdn.com/v2/latest/servisbot-utils.js https://lightning.production.helium.servismatrixcdn.com/v2/latest/bundle-messenger.js;
      connect-src 'self' https://api.production.helium.servismatrix.com/discovery/endpoint/servisbot-botty https://cognito-identity.eu-west-1.amazonaws.com https://x4bvuyqop5dobf5b7rajjrolem.appsync-api.us-east-1.amazonaws.com/graphql https://ti2oh2mtpradzjxjloufz2eydy.appsync-api.eu-west-1.amazonaws.com https://wr32shlrp2.execute-api.eu-west-1.amazonaws.com/monitoring/watchdog/metrics wss://ti2oh2mtpradzjxjloufz2eydy.appsync-realtime-api.eu-west-1.amazonaws.com/graphql;
    "
  />
</head>
<body>
  <script src="https://lightning.production.helium.servismatrixcdn.com/v2/latest/servisbot-utils.js"></script>
  <script src="https://lightning.production.helium.servismatrixcdn.com/v2/latest/bundle-messenger.js"></script>
</body>

Please note that this example CSP is not exhaustive - there may be different URLs that the messenger needs depending on the region and environment, particularly for connect-src.

Optimized (lazy-loaded) messenger bundle

This bundle relies on the execution of two scripts:

  1. servisbot-utils.js
  2. bundle-messenger-optimized.js

When using the optimized bundle, lazy loading occurs during runtime - the initial bundle-messenger-optimized.js script is smaller, and it makes network requests to the messenger CDN domain to retrieve additional .js and .css files as needed. It is important to allow these files to be imported if using a CSP, as the optimized messenger will not work properly without them.

There are several ways to allow the extra .js and .css within a CSP:

  1. script-src-elem and style-src include the CDN domain with the directory of the messenger script e.g. https://lightning.production.helium.servismatrixcdn.com/v2/latest/. Additional .js and .css live here, in /latest/static/js/<file>.js and /latest/static/css/<file>.css. The names and number of files in these directories can vary depending on the release, so it is important to allow the directory or the entire CDN domain rather than specific files as a new release’s files may be blocked if exact files are specified here.
  2. Allow the messenger by hashes. If the messenger is blocked, a console error will be shown with the hash(es) that can be whitelisted for the messenger to work.
  3. Use a nonce value (see below)

We recommend testing your CSP by launching the embedded messenger in a staging environment and checking the console and network requests, where it will be shown if any scripts, styles, images, etc. are blocked and by which CSP rule.

Using a Nonce

A nonce (number only once) is a way to whitelist content in a CSP. One drawback of using hashes for the messenger scripts is the fact that the hash changes with every release of L2. Therefore, when using a hash one must pin their L2 version, as otherwise the scripts will be blocked as soon as the hash is outdated. By using a nonce value, this drawback is bypassed.

Using a nonce:

  1. The host page generates a random base64-encoded string on every page load, this is the nonce. It must be random on each page load to prevent XSS attacks.
  2. The nonce is dynamically applied to the content security policy on the page as ‘nonce-<NONCE_VALUE_HERE>’ (see example below)
  3. The same nonce value is applied as an attribute to bundle-messenger and servisbot-utils script tags:
  • The regular bundle loads as normal this way.
  • The optimized bundle’s initial script loads using the nonce, and the messenger forwards this value when lazy loading scripts and CSS.

When using a nonce, ensure that it is applied as ‘nonce-<BASE_64_STRING>’ in the CSP, and as ‘nonce="<BASE_64_STRING>"’ as an attribute for the script element.

CSP example for the optimized bundle with a nonce (note the CDN directory for style-src is required; the nonce does not whitelist inline styles by its presence and so must be allowed directly):

<head>
  <meta
    http-equiv="Content-Security-Policy"
    content="
      default-src 'none';
      script-src 'self';
      img-src: 'self' data:,
      style-src 'self' 'unsafe-inline' https://lightning.production.helium.servismatrixcdn.com/v2/latest/;
      script-src-elem 'self' 'nonce-<NONCE_VALUE_HERE>' https://lightning.production.helium.servismatrixcdn.com/v2/latest/servisbot-utils.js https://lightning.production.helium.servismatrixcdn.com/v2/latest/bundle-messenger.js;
      connect-src 'self' https://api.production.helium.servismatrix.com/discovery/endpoint/servisbot-botty https://cognito-identity.eu-west-1.amazonaws.com https://x4bvuyqop5dobf5b7rajjrolem.appsync-api.us-east-1.amazonaws.com/graphql https://ti2oh2mtpradzjxjloufz2eydy.appsync-api.eu-west-1.amazonaws.com https://wr32shlrp2.execute-api.eu-west-1.amazonaws.com/monitoring/watchdog/metrics wss://ti2oh2mtpradzjxjloufz2eydy.appsync-realtime-api.eu-west-1.amazonaws.com/graphql;
    "
  />
</head>
<body>
  <script nonce="<NONCE_VALUE_HERE>" src="https://lightning.production.helium.servismatrixcdn.com/v2/latest/servisbot-utils.js"></script>
  <script nonce="<NONCE_VALUE_HERE>" src="https://lightning.production.helium.servismatrixcdn.com/v2/latest/bundle-messenger-optimized.js"></script>
</body>