Inline JavaScript combined with CSP Level 1

Thoughts on using inline JavaScript

Our development team is working on a new network related project. Safety is a very high priority in this project. However, implementing a Content Security Policy (CSP) for browser support has proven painful and cumbersome.

As we all know, CSP was introduced to mitigate XSS injection by blocking all external CSS / JavaScript files and preventing inline scripts from executing. Directives allow us to define a whitelist (eg "me", domain, protocols, etc.) of the content and sources that the browser will execute.

Running inline JavaScript, however, is a completely different story. CSP allows you to execute inline code using the "unsafe-inline" directive. However, adding this directive violates the CSP implementation goal.

To overcome this obstacle, our team spent some time discussing possible and viable solutions. In the following paragraphs, we will discuss a number of solutions. Any suggestions and feedback on these solutions is appreciated.

Suggestion # 1: External file

Use page specific code in an external file. This file will be generated for every request as it contains dynamic data (e.g. Google Maps key, GA tracking snippets, php-debugbar). The following idiom illustrates how this sentence can be implemented in HTML code.

<html>
    <head>
        <script src="/generated/external-file.js"></script>
    </head>
</html>

      

Pros: The client side will remain transparent as the server has to generate the file.

Cons: HTTP is a stateless protocol and dynamic data that changes with every request cannot be included in an external file (like php-debugbar).

Offer # 2: Nonce combined with CSP

CSP Level 2 supports inline styles and scripting by providing a nonce in the CSP response header. The following idiom illustrates an inline script, the nonce attribute contains a dynamically generated value.

<script nonce="nm77q3oep8l0ybxmugzewkfyacyma3n3">console.log('Hello world');</script>

      

To execute this script, the nonce must be present in the CSP response header. The following idiom illustrates how this nonce should be included in the response header.

Content-Security-Policy: script-src 'nonce-nm77q3oep8l0ybxmugzewkfyacyma3n3'

      

For security reasons, this nonce should be random and should be regenerated on every request.

Pros: Supported by CSP level 2.

Cons: Browser support is an issue (75% of all browsers implement a Level 2 CSP dating from April 10, 2017 ( http://caniuse.com/#feat=contentsecuritypolicy2 ).

Suggestion # 3: Hashing with CSP

CSP Level 2 supports inline styles and scripts by hashing the content of these elements and providing this hash in the CSP response header. The following idiom illustrates an inline script whose content will create the following SHA-256 hash: 9e8a3b5e27971b7309ff6c00f5c80644ffe8e635ce797d7eed8ee23d485a19f2

<script>console.log('Hello world');</script>

      

To execute this script, the computed hash must be present in the CSP response header. The following idiom illustrates how this hash should be included in the response header.

Content-Security-Policy: script-src 'sha256-9e8a3b5e27971b7309ff6c00f5c80644ffe8e635ce797d7eed8ee23d485a19f2;'

      

Pros: Supported by CSP level 2 and allows page caching using HTTP accelerators.

Cons: Browser support is an issue (75% of all browsers implement a Level 2 CSP dating from April 10, 2017 ( http://caniuse.com/#feat=contentsecuritypolicy2 ).

Suggestion # 4: JSON

CSP only disallows script elements that contain executable JavaScript code, which in short means that configuration data inside a script element is allowed. The following idiom illustrates a script element that contains JSON data.

<script type="application/json">
{
    "googleMapsKey": "v1zs9Bc10hMZ073S14gy",
    "analyticsProperty": "UA-192348"
}
</script>

      

See https://mathiasbynens.be/notes/json-dom-csp for details .

Pros: Very safe because it doesn't allow executable code inside script tags.

Cons: Dynamically generated JavaScript for every request (like php-debugbar) is not resolved by this solution.

Suggestion # 5: Custom nonce implementation

Implement a custom nonce solution that can be used until most browsers support CSP Level 2. The following idiom illustrates how this solution can be implemented.

See JSFiddle code (adapted to work) and source code Gist .

To execute this script, the 'unsafe-eval' directive must be included in the response header. While not recommended, it does support this approach. Apart from many frameworks like Vue.js it requires a directive to work.

The following idiom illustrates how the directive should be included in the response header.

Content-Security-Policy: script-src 'unsafe-eval'

      

Pros: Supports level 1 CSP and can be adapted to proposal # 2 without too much trouble when most browsers support level 2 CSP.

Cons: A custom implementation that needs to be thoroughly tested and requires an "unsafe-eval" directive in the CSP header.

Please share your ideas, we will use any discount!

+3


source to share


1 answer


Content security policies can be defined on each page: you can fine-tune the policy for specific pages based on their specific needs.

External files

Rather than looking for one solution that fixes all of this, I would suggest starting by moving all the "non-dynamic" inline styles and script into external files. Content security policy exists because embedded scripts cannot always be trusted. Using external files has a number of advantages over working with CSPs:

  • external resources are easier for the browser to cache;
  • more understandable for developers;
  • and facilitates compilation and minification.

Sandbox

Another "solution" to look out for is the sandbox. If the directive is present sandbox

, the page is treated as if it were loaded internally <iframe>

with the sandbox

.



More information on the sandbox can be found at: HTML5 specification .

Additional Information

Google Developer Guide: Content Security Policy .

Mozilla Developer's Guide: Content Security Policy .

The W3C Web Application Security Working Group has already begun work on the specification for the next iteration, "Content Security Level 3" .

0


source







All Articles