Swipe left or right to navigate to next or previous post
Content Security Policy (CSP) is an essential security feature that helps protect websites from cross-site scripting (XSS) attacks and other code injection vulnerabilities. One of the most effective ways to secure inline scripts is by using hashes in your CSP headers. This method allows you to specify that only trusted inline scripts—those whose content matches a specific cryptographic hash—are allowed to execute.
Inline scripts are often a target for attackers who inject malicious code, but in some cases, using inline
scripts is unavoidable. While CSP by default blocks inline scripts with the 'unsafe-inline'
directive,
using hashes allows you to permit specific inline scripts securely. Instead of allowing all inline scripts,
you can define a hash for each script and only those that match the hash will be executed.
The basic idea behind using hashes in CSP is simple. Each inline script that you wish to allow must be hashed using
a secure hashing algorithm like SHA-256, SHA-384, or SHA-512. You then specify this hash in the Content-Security-Policy
header of your HTTP response.
The browser computes the hash of each inline script and compares it with the hash values specified in the CSP header. If the hashes match, the script is allowed to execute. If they do not match, the browser will block the script, helping to prevent malicious code from running.
To implement CSP using hashes, follow these steps:
The first step is to generate a cryptographic hash of the inline script. You can use algorithms like SHA-256,
SHA-384, or SHA-512, but SHA-256 is the most commonly used. This can be done with various tools or directly in
your development environment. For example, in a command-line interface, you can use openssl
to generate a hash for the inline script content.
echo -n "console.log('This is a trusted inline script.');" | openssl dgst -sha256 -binary | openssl base64
This command will output a base64-encoded hash that you can use in your CSP header. An example of an output might be:
sha256-EXAMPLE_HASH_VALUE==
Once you have the hash, you need to add it to your CSP header. In your Content-Security-Policy
header, use the sha256-
prefix followed by the hash value you just generated. For example:
Content-Security-Policy: script-src 'self' 'sha256-EXAMPLE_HASH_VALUE==';
This directive tells the browser to allow only those inline scripts that match the specified hash. Any script with a different hash will be blocked.
To dynamically generate the hash for inline scripts in a Django application, you can use Python's hashlib
library to compute the hash of the script content and then inject it into your CSP header. Here’s an example of how to do that:
import hashlib
import base64
# Define your inline script
script = "console.log('This is a trusted inline script.');"
# Generate the SHA-256 hash
hash_value = base64.b64encode(hashlib.sha256(script.encode()).digest()).decode()
# Add the hash to the CSP header
response["Content-Security-Policy"] = f"script-src 'self' 'sha256-{hash_value}';"
This code calculates the hash for the inline script and then adds it to the response's CSP header, ensuring only trusted inline scripts are allowed.
If you have multiple inline scripts that need to be allowed, you can generate and add hashes for each of them to the script-src
directive. For example:
Content-Security-Policy: script-src 'self' 'sha256-HASH1==' 'sha256-HASH2==' 'sha256-HASH3==';
Each hash corresponds to a different inline script. The browser will compare each script's hash with the values in the CSP header, allowing only those that match to execute.
While implementing CSP with hashes is a robust security measure, it requires careful planning and maintenance to be effective and manageable. Here are detailed best practices to help you maintain and optimize your CSP policy when using hashes:
Manually generating and updating hashes can be time-consuming and error-prone, especially in larger projects. To streamline the process, integrate hash generation into your build pipeline using tools or scripts. For example:
By automating this step, you can ensure consistency and reduce the risk of forgetting to update a hash when the corresponding script changes.
Separate your inline scripts into two categories: static (unchanging) and dynamic (frequently modified or generated at runtime). Use hashes for static scripts and consider using nonces for dynamic scripts to avoid frequent updates to CSP headers.
Wherever possible, move scripts to external files and reference them using 'self'
or trusted domains in the script-src
directive. This approach simplifies your CSP management and reduces the need for hashes altogether. Inline scripts should be a last resort when externalizing scripts is not feasible.
Always use strong cryptographic algorithms such as SHA-256
, SHA-384
, or SHA-512
. Avoid using outdated or weaker algorithms, as they may not provide sufficient security and could eventually be deprecated by browsers.
Use browser developer tools to test your CSP policies and ensure they are working as intended. Look for blocked scripts in the browser console and verify that only authorized scripts are executed. Regular testing helps identify any misconfigurations or missing hashes early.
Enable CSP reporting by adding a report-uri
or report-to
directive to your CSP header. This allows browsers to send violation reports to a specified endpoint whenever a script is blocked. Review these reports to identify and address potential issues with your CSP policy.
Content-Security-Policy: script-src 'self' 'sha256-HASH_VALUE'; report-uri /csp-violation-report-endpoint;
Whenever an inline script changes, you must update its hash in the CSP header. Maintain a process to update CSP headers during deployments to ensure they stay synchronized with your scripts.
Ensure all developers understand how CSP with hashes works and the importance of maintaining the policy. Provide training or documentation for team members to follow best practices and avoid introducing new inline scripts without corresponding hash updates.
When first implementing or updating your CSP, use the Content-Security-Policy-Report-Only
header. This allows you to test your policy without actually blocking scripts, helping you fine-tune it before enforcing it fully.
Store your CSP policies in version control alongside your codebase. This practice ensures that any updates to inline scripts or CSP policies are tracked and can be rolled back if needed.
Avoid overly complex CSP policies by keeping the number of hashes in your header manageable. Group related scripts together and simplify your policies where possible to reduce the risk of errors or omissions.
If you rely on external scripts, ensure they come from trusted sources and add those domains to your script-src
directive. For example:
Content-Security-Policy: script-src 'self' https://trusted.cdn.com 'sha256-HASH_VALUE';
This approach allows you to combine hashes for inline scripts with source-based whitelisting for external resources.
When developing new features, consider the impact on your CSP policy. For example, if you know a script will require frequent updates, plan to use nonces instead of hashes for flexibility.
Using hashes in your Content Security Policy (CSP) is an effective way to allow trusted inline scripts while preventing the execution of unauthorized scripts. By leveraging cryptographic hashes, you can ensure that only scripts with the exact content you’ve authorized are executed, significantly improving your website’s security. However, remember to maintain the hashes carefully and update them whenever inline scripts change to keep your CSP working smoothly.
Want to Explore more on Content security policy - A Shield Against Modern Web Vulnerabilities, Please visit