Guide
Allowing inline scripts in a Content-Security-Policy with hashes
A Content-Security-Policy tells the browser which scripts and styles a page may run, which is the strongest defence against cross-site scripting: even if an attacker injects a <script> tag, the browser refuses to execute it. Many sites weaken that protection with 'unsafe-inline' because they have a few legitimate inline scripts. Hash sources allow exactly those scripts and nothing else. This tool finds the inline code in a page and computes the hashes.
Why unsafe-inline is a problem
'unsafe-inline' allows every inline script on the page, including the ones an attacker manages to inject, so a policy that contains it offers little protection against XSS. Listing a hash for each legitimate inline block lets the browser run those blocks and block any other inline code.
How a hash source works
A hash source is the base64-encoded SHA-256, SHA-384 or SHA-512 digest of the script’s exact text, written in quotes with the algorithm name, for example 'sha256-…'. When the browser meets an inline script, it hashes the text between the opening and closing tags and runs the script only if that hash is in the policy. Every character counts: spaces, indentation and line breaks are part of the input, and the text is encoded as UTF-8 first.
What the extractor finds
In HTML mode, the tool scans the page for inline <script> blocks, <style> blocks and event-handler attributes such as onclick="…". Scripts with a src attribute are skipped because they are allowed by origin, not by hash, and so are data blocks such as JSON-LD, import maps and templates, which browsers do not execute. Each block is listed with a preview and its hash, and the policy header below is filled in with them. In raw mode, paste a single script’s content to hash only that.
Event handlers and unsafe-hashes
Inline handlers are a special case. Since CSP Level 3, they can be allowed by hash only if the policy also contains 'unsafe-hashes', and the tool adds it when it finds handlers. That keyword re-enables a class of risk, so moving handlers into a script file with addEventListener is the better long-term fix.
Nonces as the alternative
For pages rendered by a server, a nonce is often easier: generate a fresh random value per response, put it in the header as 'nonce-…' and on each script tag as nonce="…". With 'strict-dynamic', scripts loaded by a trusted script are trusted too. The nonce button produces 128 random bits from the browser’s cryptographic generator, but a nonce only protects anything when it changes on every response, so it cannot be used in static HTML.
A worked example
The Sample page has an inline theme script, an inline style block, an external app.js, a JSON-LD block and a button with an onclick handler. The tool finds three items to hash: the script, the style and the handler. The policy reads default-src 'self'; script-src 'self' 'sha256-kKM2oKS6VUDHax3JAyy1x+3NH0h1NqCONQq6jVM5FUw=' 'unsafe-hashes' 'sha256-LdlORHyUW/rwezK0l13nW+IwcZmi78eWOCBjewMWRr4='; style-src 'self' 'sha256-VtY8xt///Rl0jNNqbGR9GPpkyX6goq/uXIfvOYgJ5GU=', followed by object-src 'none', base-uri 'self' and frame-ancestors 'self'. The external script and the JSON-LD block need no hash.
When hashes break
Because the hash covers every byte, any change to the script, even reformatting by a minifier, a template engine adding whitespace or a CMS rewriting quotes, produces a new hash and the browser blocks the old script. Hash the final HTML as it is served, and regenerate the policy whenever an inline block changes; build steps can automate this.
Related tools
- Hash Generator computes SHA digests of any text or file.
- Nginx Config Generator shows where to add the header.
- HTML to JSX moves inline markup into components.
- Code Minifier produces the final script text to hash.
Checked against the current version of the CSP Hash Generator on .

