I kept pasting production JWTs into random online decoders and then
immediately regretting it. Most of them are client side, but you can't
tell that by looking, and "trust me" isn't a security property.
So I built one where you don't have to.
The page sets Content-Security-Policy: connect-src 'none'. The browser
then refuses every fetch, XHR, WebSocket and beacon the page could try.
Keys go into WebCrypto with extractable: false, so the page can't read
them back after import. And there's a Playwright test asserting zero
outbound requests while decoding, verifying and signing. It runs on
every deploy.
Two things worth mentioning before someone else finds them.
CSP doesn't block navigation. A malicious build could still leak a token
via window.location, so this isn't a sandbox. What connect-src 'none'
kills is every quiet channel, which is the part I actually cared about.
And Cloudflare injects its own analytics beacon into pages it serves, so
you'll see a failed request to static.cloudflareinsights.com in the
network tab with a CSP violation in the console. The policy stops it
running. Rather point at it than have you spot it and wonder what else
is in there.
If you want to check any of it: https://jamuny.com/verify/ walks through
the network panel, reading the CSP, and just pulling your wifi and
carrying on working.
Same idea behind 18 other text tools (JSON formatter, regex tester,
diff, CSV to JSON, hashes, UUIDs): https://jamuny.com
Astro, no UI framework, fonts self hosted since loading Google Fonts
would defeat the point somewhat. All static HTML, works with JS off.
pop3zxcv•54m ago
So I built one where you don't have to.
The page sets Content-Security-Policy: connect-src 'none'. The browser then refuses every fetch, XHR, WebSocket and beacon the page could try. Keys go into WebCrypto with extractable: false, so the page can't read them back after import. And there's a Playwright test asserting zero outbound requests while decoding, verifying and signing. It runs on every deploy.
Two things worth mentioning before someone else finds them.
CSP doesn't block navigation. A malicious build could still leak a token via window.location, so this isn't a sandbox. What connect-src 'none' kills is every quiet channel, which is the part I actually cared about.
And Cloudflare injects its own analytics beacon into pages it serves, so you'll see a failed request to static.cloudflareinsights.com in the network tab with a CSP violation in the console. The policy stops it running. Rather point at it than have you spot it and wonder what else is in there.
If you want to check any of it: https://jamuny.com/verify/ walks through the network panel, reading the CSP, and just pulling your wifi and carrying on working.
Same idea behind 18 other text tools (JSON formatter, regex tester, diff, CSV to JSON, hashes, UUIDs): https://jamuny.com
Astro, no UI framework, fonts self hosted since loading Google Fonts would defeat the point somewhat. All static HTML, works with JS off.
Interested to hear where I've got the CSP wrong.