Вопрос:

Inline JavaScript in conjunction with CSP Level 1

javascript json http inline content-security-policy

1206 просмотра

1 ответ

439 Репутация автора

Thoughts on using inline JavaScript

Our development team is working on a new web related project. Within this project security has a very high priority. However implementing the Content Security Policy (CSP) with regards to browser support turned out to be 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 to be executed. Directives allow us to define a whitelist (e.g. 'self', domain, protocols, etc..) of content and sources that the browser will execute.

Executing inline JavaScript code however is a completely different story. CSP does allow inline code to be executed using the 'unsafe-inline' directive. However adding this directive defeats the purpose of implementing CSP.

In order to overcome this hurdle our team has spent some time discussing possible and viable solutions. In the following paragraphs we will discuss a number of solutions. Any suggestions and feedback to these solutions are welcome.

Proposal #1: External file

Serve page specific code in an external file. This file would be generated on each request since it contains dynamic data (e.g. Google Maps key, GA tracking snippets, php-debugbar). The following idiom illustrates how this proposal could be implemented in HTML code.

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

Pros: Client side would remain transparent since the server has to generate the file.

Cons: HTTP is a stateless protocol and dynamic data which changes with each request cannot be included in the external file (e.g. php-debugbar).

Proposal #2: Nonce in conjunction with CSP

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

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

In order for this script to execute, the nonce needs to be present in the CSP response header. The following idiom illustrates how this nonce must be incorporated into the response header.

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

For security reasons this nonce must be random and has to be regenerated on each request.

Pros: Supported by level 2 of CSP.

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

Proposal #3: Hashing in conjunction with CSP

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

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

In order for this script to execute, the computed hash needs to be present in the CSP response header. The following idiom illustrates how this hash must be incorporated into the response header.

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

Pros: Supported by level 2 of CSP and allows caching of pages through the use of HTTP accelerators.

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

Proposal #4: JSON

CSP only prohibits script elements which contain executable JavaScript code which in short means configuration data within a script element is allowed. The following idiom illustrates a script element containing JSON data.

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

See https://mathiasbynens.be/notes/json-dom-csp for more information and examples.

Pros: Very safe because it does not allow executable code inside script tags.

Cons: Dynamically generated JavaScript code for each request (e.g. php-debugbar) is not solved by this solution.

Proposal #5: Custom nonce implementation

Implement a custom nonce solution which might be used until most browsers support CSP level 2. The following idiom illustrates how this solution might be implemented.

See JSFiddle code (adapted to work) and or Gist with the original code.

In order for this script to execute, the 'unsafe-eval' directive has to be supplied in the response header. Although this is not recommended, this support for this approach. Besides many frameworks like Vue.js require the directive to work.

The following idiom illustrates how the directive must be incorporated in the response header.

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

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

Cons: Custom implementation which must be thoroughly tested and requires "unsafe-eval" directive in the CSP header.

Please share your thoughs, we would appriciate any feeback!

Автор: Dygnus Источник Размещён: 10.04.2017 03:13

Ответы (1)


0 плюса

706 Репутация автора

The Content Security Policy can be defined on a page-by-page basis: you can fine-tune the policy for specific pages based on their specific needs.

External files

Instead of trying to find one a solution that fixes it all, I would suggest to start by moving all the 'non-dynamic' inline styles and script to external files. The Content Security Policy exists because inline scripts can't always be trusted. The usage of external files has a number of advantages other than working well with CSP:

  • external resources are easier for browsers to cache;
  • more understandable for developers;
  • and conducive to compilation and minification.

Sandboxing

Another 'solution' worth looking at is sandboxing. If the sandbox directive is present, the page is treated as though it was loaded inside of an <iframe> with a sandbox attribute.

More information about sandboxing can be found at: HTML5 specification.

More information

The Google developer guide: Content Security Policy.

The Mozilla developer guide: Content Security Policy.

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

Автор: Roald Nefs Размещён: 11.04.2017 08:39
Вопросы из категории :
32x32