Content Security Policy (CSP)
Quick Reference Guide


Using a nonce with CSP

A nonce is a randomly generated token that should be used only one time.

What is a nonce?

The word nonce can be defined as a word or phrase that is intended for use only once. If you were a spy, you might come up with a nonce as a code word to authenticate a rendezvous.

The important thing to remember for nonces with respect to (CSP) is that we only use our nonce once (for one request), and they should be so random that no one could guess it.

Example Nonce Usage

Using a nonce is one of the easiest ways to allow the execution of inline scripts in a Content Security Policy (CSP). Here's how one might use it with the CSP script-src directive:

script-src 'nonce-rAnd0m';
NOTE: We are using the phrase: rAnd0m to denote a random value. You should use a cryptographically secure random token generator to generate a nonce value. The random nonce value should only be used for a single HTTP request.

Now we can allow an inline <script> tag to execute by adding our random nonce value in the nonce attribute of the script tag:

<script nonce="rAnd0m">
	doWhatever();
</script>

What is a CSP nonce for?

So why do we need a to add a csp nonce to every inline script block when we use CSP? The short answer is that when you enable CSP it will disable inline script tags, so code like the following will not execute:

<script>
	thisWillNotExecute();
</script>

This is because the browser doesn't know the difference between JavaScript code that you wrote and intend for the user to execute vs code that an attacker has injected into the page (for example via an XSS vulnerability). These inline script blocks are dangerous, and the nonce lets the browser know that the server intended on serving this script block if and only if the nonce attribute in the script tag matches the nonce value in the Content-Security-Policy header.

Avoid this common nonce mistake

If you are outputting variables inside a nonce protected script tag, you could cancel out the XSS protection that CSP is giving you.

For example assume you have a URL such as /example/?id=123 and you are outputting that id value from the URL in your script block:

<script nonce="#request.nonce#">
	var id = #url.id#
</script>

In the above example assume that the variable token #url.id# is the id value from the query string. Now an attacker could request the URL: /example/?id=doSomethingBad(), and your application would send back:

<script nonce="rAnd0m">
	var id = doSomethingBad()
</script>

As you can see we just threw away all of the cross site scripting protections of CSP by improperly using the nonce.

Rules for Using a CSP Nonce

If you do need to use a variable like in the above example, you need to make sure that it has been validated. In this case we could make sure it is a valid integer. In more complex cases you would need pass the variable through an encoder that would escape javascript. For example in the Java OWASP ESAPI library the encodeJavaScript function could be used, or in CFML the encodeForJavaScript function could be used.

What if a CSP nonce doesn't make sense?

In some situations using a nonce doesn't make sense, in those cases you can use a CSP hash instead of a nonce.

There is one other workaround to this problem called unsafe-inline, but as its name suggests it is not really a good idea to use it (except in specific conditions).

Nonce Browser Support

The nonce source list directive was added to CSP Level 2. This means that support has existed since 2015 in Chrome and Firefox, Safari 10+ or Edge 15+.

Nonces are not supported at all in Internet Explorer, you need to use the Edge browser for nonce support instead.

CSP Developer Field Guide

CSP Developer Field Guide

Want to learn the ins and outs CSP? Grab a copy of the CSP Developer Field Guide. It's a short and sweet guide to help developers get up to speed quickly.

Grab a Copy

Struggling to stay on top of security advisories?

Advisory Week is a weekly roundup of all the security advisories published by the major software vendors.