Content Security Policy (CSP)
Quick Reference Guide


The CSP nonce Guide

Learn how to use a CSP nonce to allow the loading and execution of a script or style tag when a Content-Security-Policy is enabled.

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.

In cryptography a nonce may be used to prevent replay attacks, where the attacker captures and replays a previously used message.

The two most important things to remember when using a nonce, especially with respect to (CSP), is that we only use our nonce once (for one request), and the nonce should be so random that no one could guess it.

A CSP nonce will be a randomly generated token that we use exactly one time.

Example Script 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 a script nonce with the CSP script-src directive:

script-src 'nonce-rAnd0m';
NOTE: We are using the phrase: rAnd0m to denote a random nonce value. You should use a cryptographically secure random token generator to generate a CSP 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 script 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 script nonce attribute lets the browser know that the server intended on serving this script block if and only if the nonce attribute value in the script tag matches the nonce value in the Content-Security-Policy header.

What is a CSP style nonce?

The HTML <style> tag can also accept the nonce attribute. Because CSS styles can also be used to load or request resources or potentially execute client side code, inline style tags are also blocked by default once a CSP policy is enabled.

In order to allow a style tag to run, we can set the style tag nonce attribute like this:

<style nonce="rAnd0m">
	.alert { color: red; }
</style>

And our Content-Security-Policy header would include the random style nonce value in the style-src directive, like this:

style-src 'nonce-rAnd0m';

In this case the inline style tag is allowed to run thanks to the style nonce provided.

Using a Nonce on External Scripts

You can use a CSP nonce on external scripts or stylesheets to allow them to execute. For example if we have a CSP policy similar to the following:

Content-Security-Policy: default-src 'none';script-src 'nonce-rAnd0m'

You can then add the nonce attribute to the script tag to allow jQuery to load without adding code.jquery.com to the CSP policy.

<script src="https://code.jquery.com/jquery-3.7.1.min.js" 
	nonce="rAnd0m"
	integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" 
	crossorigin="anonymous"></script>

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.

Considering Nonce vs Hash

An alternative to using a CSP nonce, is the CSP hash. There are pros and cons to using nonce vs using a hash, but both approaches allow you to allow inline script or inline CSS with CSP.

Pros of using a Nonce vs a Hash

Cons of using a Nonce vs a Hash

How long should the nonce be?

One of the first questions you might ask yourself when implementing a content security policy script nonce, is how many characters should it be?

In general you can use the same length you might use for a session identifier, or at least 128 bits. A 128 bit nonce would be 32 characters of a hexadecimal string, or about 24 characters of a base64 encoded string.

How can you generate a nonce value?

There are many ways to generate a random value for use with a csp script nonce or style nonce. Which ever option you choose make sure that you are relying on a library that uses a cryptographically secure random generator. Depending on what programming language you use, here are a few common ways to do it:

Generate CSP Nonce With PHP

bin2hex(openssl_random_pseudo_bytes(32))

Generate CSP Nonce With Python

import secrets
nonce = secrets.token_urlsafe(32)

Generate CSP Nonce in CFML / ColdFusion

generateSecretKey('aes')

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.