2 pointsby pop3zxcv4 hours ago1 comment
  • pop3zxcv4 hours ago
    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.

    Interested to hear where I've got the CSP wrong.