Securing ZK without Unsafe-Eval and Unsafe-Inline CSP

From Documentation


DocumentationZK Developer's ReferenceSecurity TipsContent Security PolicySecuring ZK without Unsafe-Eval and Unsafe-Inline CSP
Securing ZK without Unsafe-Eval and Unsafe-Inline CSP


General considerations

'unsafe-eval' and 'unsafe-inline' script sources

Scripts loaded by web browsers can originate from many different type of sources, such as being loaded from an external file. Two of these sources that are important in regard to ZK's client engine are eval and inline.

'unsafe-eval' source expression

The 'unsafe-eval' source expression controls code created by evaluating strings in the client's JavaScript engine. The ZK client engine uses evaluated scripts when building client-side objects. As a result, ZK clients require access to the "eval" source.

See the MDN CSP documentation for more information.

'unsafe-inline' source expression

The 'unsafe-inline' source expression controls code declared inside `script` elements. The ZK client engine uses script elements to load itself during page creation, and to load additional library resources, such as wpd files containing widget classes.

<script>
    //This is an inline script
    function foo(){
        return "bar";
    }
</script>

See the MDN CSP documentation for more information.

Unsecured CSP for inline and eval scripts

A simple-to-implement but unsecured way to allow ZK scripts to use the eval and inline sources types is to simply declare the 'unsafe-inline' and 'unsafe-eval' sources to be allowed in the page.

However, using this approach means that any script may be using the 'unsafe-eval' or 'unsafe-inline' sources to create code, which in turns creates opportunities for XSS attacks, which the CSP is meant to protect against.

Securing 'unsafe-eval' and 'unsafe-inline' with nonce and 'strict-dynamic' source expression

As a secure alternative to allowing all scripts to use 'unsafe-inline' and 'unsafe-eval' as allowed sources, we can use a nonce (a unique ID) declared in the CSP header to only allow properly identified scripts to be created by unsafe-inline and unsafe-eval sources.

This can be achieved using the 'strict-dynamic' CSP.

The 'strict-dynamic' source expression specifies a nonce (or hash), which act as a one-time-use password. Scripts in this page which have the nonce declared as an attribute will be granted the authorization to execute according to the source expression contained in the 'strict-dynamic' policy.

Response header:

    Content-Security-Policy: script-src 'strict-dynamic' 'nonce-abc123'
<script nonce="abc123">
    //This inline script can be executed, since it holds a nonce matching the CSP header
    function foo(){
        return "bar";
    }
</script>
<script>
    //This inline script cannot be executed, since it doesn't hold a nonce matching the CSP header
    function baz(){
        return "qux";
    }
</script>

Note: When inspecting the script element from the browser's developer tools, the nonce attribute will not be visible. This is intended, as it prevents other sources from trying to obtain a valid nonce in order to bypass security during the page lifecycle.

A nonce content attribute represents a cryptographic nonce ("number used once") which can be used by Content Security Policy to determine whether or not a given fetch will be allowed to proceed. The value is text.

Elements that have a nonce content attribute ensure that the cryptographic nonce is only exposed to script (and not to side-channels like CSS attribute selectors) by taking the value from the content attribute, moving it into an internal slot named CryptographicNonce, exposing it to script via the HTMLOrSVGElement interface mixin, and setting the content attribute to the empty string. Unless otherwise specified, the slot's value is the empty string.

Version History

Version Date Content
     



Last Update : 2023/08/01

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.