codelessgenie blog

Firefox CSP SHA-256 Inline Script Whitelisting Not Working? Troubleshooting Guide

Content Security Policy (CSP) is a critical web security layer that helps prevent cross-site scripting (XSS), data injection, and other code injection attacks by controlling which resources a browser is allowed to load. One of CSP’s most powerful features is its ability to whitelist inline scripts using cryptographic hashes (e.g., SHA-256), allowing specific trusted inline code while blocking all others.

However, developers often encounter frustration when SHA-256 inline script whitelisting works in browsers like Chrome but fails in Firefox. This discrepancy stems from subtle differences in how Firefox parses CSP directives, generates hashes, and enforces policies.

In this guide, we’ll demystify why Firefox might reject your SHA-256-whitelisted inline scripts and provide a step-by-step troubleshooting process to resolve the issue.

2026-01

Table of Contents#

  1. Understanding CSP and Inline Script Whitelisting

    • What is Content Security Policy (CSP)?
    • The Risk of Inline Scripts
    • How SHA-256 Hashing Works for Whitelisting
  2. Common Reasons SHA-256 Whitelisting Fails in Firefox

    • Incorrect Hash Generation
    • Syntax Errors in CSP Directives
    • Case Sensitivity Issues
    • Firefox-Specific Whitespace/Encoding Quirks
    • Mixed Content or HTTPS Problems
    • Browser Version Compatibility
    • Inline Event Handlers (onclick, onload, etc.)
  3. Step-by-Step Troubleshooting Guide

    • Step 1: Verify the CSP Header is Being Sent
    • Step 2: Generate the Correct SHA-256 Hash
    • Step 3: Validate CSP Directive Syntax
    • Step 4: Inspect CSP Violations in Firefox DevTools
    • Step 5: Check for Firefox-Specific Quirks
    • Step 6: Test with a Minimal Example
    • Step 7: Update Firefox and Check Compatibility
  4. Advanced Scenarios and Workarounds

    • Handling Inline Event Handlers with unsafe-hashes
    • Dynamic Inline Scripts and CSP
    • Combining Hashes with strict-dynamic
  5. Conclusion

  6. References

1. Understanding CSP and Inline Script Whitelisting#

What is Content Security Policy (CSP)?#

CSP is a browser security mechanism enforced via HTTP headers or <meta> tags. It lets website owners define a "whitelist" of trusted sources for resources like scripts, stylesheets, images, and more. By default, CSP blocks risky practices like inline scripts and eval(), unless explicitly allowed.

The Risk of Inline Scripts#

Inline scripts (e.g., <script>console.log('Hi');</script>) are a major XSS vector. Attackers can inject malicious inline code into web pages if input sanitization fails. CSP mitigates this by blocking inline scripts unless explicitly whitelisted.

How SHA-256 Hashing Works for Whitelisting#

Instead of using unsafe-inline (which disables all inline script protections), CSP allows you to whitelist specific inline scripts using their SHA-256 hash. Here’s how it works:

  1. Compute the SHA-256 hash of the inline script’s exact content (excluding <script> tags).
  2. Encode the hash in Base64.
  3. Add the hash to your CSP script-src directive (e.g., script-src 'sha256-abc123...').

Browsers will only execute the inline script if its hash matches the whitelisted value.

2. Common Reasons SHA-256 Whitelisting Fails in Firefox#

Incorrect Hash Generation#

The most common issue is generating an invalid hash. This happens if:

  • You include <script> tags in the hash (only the script content is hashed).
  • You forget to exclude trailing newlines (e.g., using echo without -n in Linux).
  • The script content has whitespace (spaces, tabs, newlines) that differs between your source and the browser’s parsing.

Syntax Errors in CSP Directives#

Firefox strictly enforces CSP syntax. Common mistakes include:

  • Missing quotes around the hash (e.g., sha256-abc123 instead of 'sha256-abc123').
  • Typos (e.g., sha256 instead of sha256- prefix).
  • Conflicting directives (e.g., script-src 'self' overriding your hash).

Case Sensitivity Issues#

CSP hashes are case-sensitive. A hash like 'sha256-AbC123' will fail if the browser expects 'sha256-abc123' (or vice versa).

Firefox-Specific Whitespace/Encoding Quirks#

Firefox parses inline scripts more strictly than Chrome in some cases:

  • Whitespace: Firefox includes all whitespace (e.g., leading/trailing spaces, tabs) when computing the hash. If your script has a trailing space you forgot to include in the hash, Firefox will block it.
  • Encoding: Firefox may handle HTML entities (e.g., &lt; for <) or escaped characters differently than Chrome.

Mixed Content or HTTPS Issues#

If your site uses HTTPS but the CSP header is served over HTTP (or vice versa), Firefox may ignore the CSP policy. Always serve CSP over HTTPS.

Browser Version Compatibility#

Older Firefox versions (pre-40) do not support SHA-256 hashing for inline scripts. Ensure users are on Firefox 40+.

Inline Event Handlers (onclick, onload, etc.)#

Inline event handlers like <button onclick="doSomething()"> are treated as inline scripts but require special handling. SHA-256 hashing alone won’t whitelist them unless you also include the unsafe-hashes directive (supported in Firefox 75+).

3. Step-by-Step Troubleshooting Guide#

Step 1: Verify the CSP Header is Being Sent#

First, confirm Firefox is receiving your CSP header.

How to check:

  • Open Firefox DevTools (F12) → Network tab → Reload the page → Select the main HTML request → Response Headers → Look for Content-Security-Policy or Content-Security-Policy-Report-Only.

If the header is missing, fix your server configuration (e.g., Apache .htaccess, Nginx nginx.conf, or framework-specific CSP middleware).

Step 2: Generate the Correct SHA-256 Hash#

A invalid hash is the #1 culprit. Follow these steps to generate it correctly:

Example Inline Script:#

<script>
  console.log('Hello, CSP!');
</script>

How to Generate the Hash:#

  1. Extract the script content (excluding <script> tags):
    console.log('Hello, CSP!'); (note: include all whitespace, like the newline after <script> if present).

  2. Compute the SHA-256 hash (use openssl or an online tool):

    • Linux/macOS:

      echo -n "console.log('Hello, CSP!');" | openssl dgst -sha256 -binary | base64

      The -n flag ensures echo doesn’t add a trailing newline (critical for accuracy).

    • Windows (PowerShell):

      $scriptContent = "console.log('Hello, CSP!');"
      $bytes = [System.Text.Encoding]::UTF8.GetBytes($scriptContent)
      $sha256 = [System.Security.Cryptography.SHA256]::Create()
      $hashBytes = $sha256.ComputeHash($bytes)
      [Convert]::ToBase64String($hashBytes)
    • Online Tool: Use Report URI’s CSP Hash Generator.

Step 3: Validate CSP Directive Syntax#

Ensure your CSP directive is formatted correctly.

Correct Example:

Content-Security-Policy: script-src 'self' 'sha256-abc123def456...';

Common Syntax Mistakes:

  • Missing quotes around the hash: sha256-abc123 → Should be 'sha256-abc123'.
  • Extra spaces: ' sha256-abc123 ' (spaces inside quotes break the hash).
  • Using sha256 instead of sha256-: 'sha256abc123' → Invalid prefix.

Step 4: Inspect CSP Violations in Firefox DevTools#

Firefox’s DevTools will tell you why a script was blocked.

How to check:

  1. Open DevTools → Console tab. Look for errors like:
    Content Security Policy: The page’s settings blocked the loading of a resource at inline ("script-src").
    
  2. Click the error to expand details. Firefox often shows the expected hash (the one it computed for your inline script). Compare this to your whitelisted hash—they must match exactly.

Step 5: Check for Firefox-Specific Quirks#

Firefox may differ from Chrome in how it parses inline scripts. Test these scenarios:

  • Whitespace: If your script has trailing spaces (e.g., console.log('test'); ), include them in the hash.
  • Newlines: A script with console.log('test');\n (newline at end) will have a different hash than one without.
  • Encoding: If your script uses escaped characters (e.g., console.log(\'test\');), ensure the hash is computed on the decoded content (not the escaped version).

Step 6: Test with a Minimal Example#

Isolate the issue with a minimal HTML file:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-abc123def456...';">
</head>
<body>
  <script>console.log('Minimal test');</script>
</body>
</html>

Host this file locally (e.g., with python -m http.server) and test in Firefox. If it works, the issue is likely in your larger codebase (e.g., conflicting directives, dynamic script modification).

Step 7: Update Firefox and Check Compatibility#

Ensure you’re using the latest Firefox version. Older versions may lack support for:

  • SHA-256 hashing (Firefox 40+ required).
  • unsafe-hashes (Firefox 75+ required for inline event handlers).

4. Advanced Scenarios and Workarounds#

Handling Inline Event Handlers with unsafe-hashes#

Inline event handlers (e.g., onclick) require the unsafe-hashes directive in script-src to work with SHA-256 hashing.

Example:

Content-Security-Policy: script-src 'self' 'unsafe-hashes' 'sha256-abc123...';

Note: unsafe-hashes weakens CSP slightly, so only use it if absolutely necessary.

Dynamic Inline Scripts and CSP#

If your inline script is dynamically generated (e.g., with server-side variables), ensure the hash is computed on the final rendered content (not the template). For example, a script like <script>var user = "<?= $user ?>";</script> must have a hash based on the rendered value of $user.

Combining Hashes with strict-dynamic#

For complex apps, use strict-dynamic to trust scripts loaded by whitelisted inline scripts. This reduces reliance on hashes for every script:

Content-Security-Policy: script-src 'sha256-abc123...' 'strict-dynamic';

5. Conclusion#

Troubleshooting Firefox CSP SHA-256 issues boils down to:

  • Generating the correct hash (exact script content, no extra whitespace/newlines).
  • Ensuring valid CSP syntax (quotes around hashes, correct prefixes).
  • Using Firefox DevTools to inspect violations and compare expected vs. actual hashes.

By following this guide, you’ll resolve most inline script whitelisting issues and secure your site with CSP.

6. References#