A Deep Dive into Hashes and Nonces: Enhancing Web Security through Content Security Policies
Introduction
If you don’t openly admit to strangers that your house has an unlocked backdoor, then you should never set ‘unsafe-inline’ for your script-src in a CSP. This is essentially saying, in computer jargon, I am formally inviting skilled adversaries to launch XSS attacks on this website.
Maybe you want to practice building a CSP, just like a small child practices on making cookies with an easy bake oven… but they didn’t really bake, and you didn’t really build an effective ‘Strict CSP’.
A strict CSP works by controlling the resources that a web page is allowed to load. Two common mechanisms in CSP are hashes and nonces, each serving specific purposes in securing web applications. This article delves into the differences between hashes and nonces, their appropriate use cases, and provide code examples to illustrate their implementation.
CSP Hashes
Inline scripts or styles in CSP require the specification of a hash of their content. When the browser encounters an inline script or style, it computes the hash and verifies it against the one provided in the CSP. Execution of the content is permitted if the hashes match; otherwise, it is prevented.
Example of Using Hashes
To use hashes, you must generate the hash for the inline script or style content and include it in the CSP header.
- Inline Script Example:
<html lang="en"> <head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-abc123xyz';">
<title>Hash Example</title>
</head>
<body>
<script> console.log('Hello, world!'); </script>
</body> </html>
- Generating the Hash: Use a tool or online service to generate the hash of
console.log('Hello, world!');
echo -n "console.log('Hello, world!');" | openssl dgst -sha256 -binary | openssl base64
This will output a base64 encoded hash, which you include in the CSP directive.
When to Use Hashes
Hashes are particularly useful when you have a limited number of inline scripts or styles that do not change frequently. They provide a straightforward way to ensure the integrity of inline content without needing to manage unique tokens.
CSP Nonces
Nonces are random values that are generated and embedded in each request. These values are used to whitelist specific inline scripts or styles for a single page load. Each nonce should be unique and unpredictable to prevent attackers from reusing them.
Example of Using Nonces
To use nonces, you need to generate a nonce value on the server side and embed it in the CSP header and the inline scripts or styles.
- Generating a Nonce: in python
import secrets nonce = secrets.token_hex(16
) - Embedding the Nonce:
<head> <meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc123xyz';">
<title>Nonce Example</title>
</head>
<body>
<script nonce="abc123xyz">
console.log('Hello, world!');
</script>
</body> </html>
When to Use Nonces
Nonces are more flexible and powerful than hashes, especially in dynamic web applications where the inline content changes frequently. Here are some scenarios where nonces are particularly advantageous:
- Dynamic Content: If your application generates inline scripts or styles dynamically, nonces provide a secure way to whitelist them without needing to regenerate hashes for each change.
- Third-Party Integrations: When integrating third-party libraries that require inline scripts, using nonces allows you to securely include these scripts without knowing their exact content beforehand.
- Complex Applications: In applications with complex frontend logic that involves numerous inline scripts or styles, managing hashes can become cumbersome. Nonces simplify this by allowing you to generate and embed unique tokens on each request.
Combining Hashes and Nonces
While hashes and nonces are typically used independently, there may be scenarios where a combination of both provides the best security. For example, you might use hashes for static inline content that rarely changes and nonces for dynamic content.
Conclusion
Never unsafe-inline
your script-src
.
As soon as you unsafe-inline
your script-src
, you’ve declared your website Naked and Vulnerable
, come and get me lions, tigers, bots, and attackers. Just like a Dateline story that ends in tragedy, ‘unsafe-inline’ is the wrong way to label your website or web application to the open Internet.
Understanding when to use CSP hashes versus nonces is critical for securing modern web applications. Hashes are ideal for static, infrequently changing content, while nonces offer flexibility for dynamic scripts.
If getting to the Green Score without 'unsafe-inline'
is a challenge for you, this is normal. NetDevs is a preferred contractor for developers, product managers, and SecOps leaders, and we invite you to learn more about us.
We are a USA-native security team certified in Enterprise Security, Microsoft Security, Cloud Security. What sets us apart is our advanced skills in full-stack app development and secure code conversions. If you have a small project, like a CSP, consider our affordable Fiverr offerings for CSP for WordPress, CSP for Drupal, and CSP for Mobile Apps.
If you have a medium project or larger, connect with us directly and let’s open a conversation.