Content Security Policy for the JSP-Loginapp

A Content Security Policy (CSP) [1] allows preventing certain XSS, clickjacking, and other code injection attacks. This is achieved by only allowing approved content (such as scripts, styles, frames, fonts, images, etc.) to execute in the browser.

It is recommended to enable the Airlock IAM Content Security Policy. As a defense in depth mechanism, it allows reducing risks of XSS, clickjacking, and other code injection attacks.

The policy is defined by the server in the Content-Security-Policy header and enforced by the browser. Note that the browser support for CSP varies a lot, and especially older browsers do not support the most recent CSP version or have no CSP support at all, see [4]. To deal with this situation, the CSP provided by Airlock IAM contains potentially redundant policies for multiple versions of the CSP specification.

What does the Airlock IAM CSP do?

Once the CSP feature is activated, IAM adds a CSP HTTP header whenever a JSP page is returned.

Consider the following example:

Content-Security-Policy: default-src 'self'; object-src 'none'; script-src 'nonce-milXqzvec4bEkKJi5z35imBH9A043R1jKzWoVM5DsT4' 'strict-dynamic' 'unsafe-inline' 'self'; img-src 'self' data:; style-src 'unsafe-inline' 'self'; base-uri 'none'; frame-ancestors 'none';

A nonce is added both in the header (see above) and in all HTML <script> tags:

<script nonce="milXqzvec4bEkKJi5z35imBH9A043R1jKzWoVM5DsT4"> (...) </script>

The purpose of the nonce is to allow the browser to block attacker injected JavaScript code.

  • Nonces are handled as follows by browsers supporting CSP version 2 and 3:
  • The browser verifies that the nonce value in the header and those in the script tags are identical. This ensures that the server provided both header and all script tags.
  • The server will generate new nonce values for each request. This renders script injection difficult since it is hard for an attacker to predict the nonce.

What does the Airlock IAM CSP achieve?

The policy contains several directives, such as:

script-src 'nonce-milXqzvec4bEkKJi5z35imBH9A043R1jKzWoVM5DsT4=' 'strict-dynamic' 'unsafe-inline' 'self';

The directives are used to define approved content. Browsers supporting CSP will read the directives and only allow content that is explicitly approved by the policy. For example, modern browsers with CSP 3 support interpret the above directive ensuring that every HTML script tag must contain a 'nonce' attribute with a matching nonce. (This is a slight simplification, as strict-dynamic allows scripts to load dependencies [2].) This is an XSS protection: an attacker script inserted through an XSS vulnerability will not be executed under the assumption that the attacker is unable to guess the nonce or modify the CSP header.

Discussing the guarantees of the IAM CSP in full detail is beyond the scope of this document.

  • For detailed information we refer to the following resources:
  • IAM implements a strict CSP, a best practice proposed by Google. For a detailed discussion, please refer to [3]. Strict CSP aims at:
    • Providing a good level of security for all CSP versions (see below).
    • Creating policies that are maintainable: historically, policies tended to be long and complicated.
  • Browser support for CSP varies a lot [4]. CSP exists in versions 1, 2, and 3. Users may use browsers that do not support CSP at all (such as Internet Explorer), or old versions of e.g. Firefox that do not support CSP in the most recent version 3. A useful tool for analyzing how a given CSP is interpreted in the three CSP versions can be found in [5].
  • Details on the policies of CSP version 3 can be found in [1].