Leveraging Cloudflare Workers to simplify a strict, nonce-based Content Security Policy (CSP) deployment
Not long ago, the Google security team demonstrated that the vast majority of whitelist-based Content Security Policies deployed today are bypass-able. In doing so, nonce-based CSP was identified as a viable solution. The team at Google was able to create supporting tools and implement browser-level changes to make nonce-based CSP easier to implement.
Nevertheless, nonce-based CSP is still challenging to implement as it requires random nonces to be generated and served in markup across an entire web application. In some cases a nonce must be generated and made available across disparate pieces of server-side web technology that are used to generate web content.
At Postmates, as we have started exploring the deployment of nonce-based CSP we have also been experimenting with Cloudflare Workers. As it turns out, Cloudflare Workers enable a clever approach to nonce generation that can ease deployment of a strict nonce-based CSP. Specifically:
- Cloudflare Workers may be used to generate a random nonce on a per-request basis.
- The generated nonce can then be applied in a strict CSP, as shown in Example 1 below. This CSP may be served to client web browsers and enforced as necessary.
- The Cloudflare worker generates a header containing the nonce which can be used in the request back to the web frontend. (See Example 2 below.)
The core Cloudflare worker code looks like this:
With this configuration in place, Cloudflare Workers will serve up CSP. It’s important to whitelist Cloudflare’s IP addresses and follow related best practice so that requests cannot bypass Cloudflare.
When a particular component within markup needs the nonce, it can be retrieved via the incoming request header:
Since the nonce will be replayed into the page, it’s important to strictly validate the format of the nonce itself. For example:
The fact that the nonce is supplied in a header also conveniently prevents an attacker from supplying the nonce in a cross-origin navigational request, though of course it should be assumed that an attacker can directly submit their own request containing a malicious nonce.
The overall advantage of this approach is that Cloudflare Workers enable easy centralized nonce generation. Nonce generation and distribution within the frontend web stack would otherwise be quite awkward. With the worker-based approach, nonces are generated outside of the primary frontend web stack and thus they can be included in content simply by reading and validating a request header. There’s no need to wire up a custom mechanism to share a nonce across a complex frontend environment. Additionally, the worker-based approach allows us to ensure full coverage even for error messages and other bits of served content that could fall out of scope if CSP header generation were implemented closer to the main web application logic.
Finally, it’s helpful to maintain the CSP within Cloudflare Workers if only to allow for policy adjustments on a per-route basis.
We are still experimenting with the Cloudflare Worker-based nonce generation approach as our CSP deployment takes shape. So far it looks to be a real time saver, allowing us to deploy CSP quickly and flexibly.
This post was written by David Ross, Staff Security Engineer at Postmates.