safepaste jwt

JWT decoder

Paste a JSON Web Token to read its header and claims, decoded directly in this tab. The token never goes anywhere, so our servers never see it.

Token

What happens to what you paste

Nothing happens to it beyond what you asked for. It is decoded inside this browser tab, and it is gone as soon as you close the tab. SafePaste has no account, no database and no analytics, so there is nothing for it to be stored in.

How your browser enforces this

The page includes a Content Security Policy of connect-src 'none'. That makes fetch, XMLHttpRequest, WebSocket, EventSource and sendBeacon fail in the browser itself, whatever the code on this page tries to do. Images and fonts are restricted to data that is already inside the file, and form-action 'none' prevents all form submission.

You do not have to take our word for it. Open your browser's developer tools, watch the Network tab while you use the page, and confirm that it stays empty after the page itself has loaded.

What the host can see

This page is served by Cloudflare Pages. Like any web server, it sees the request for the page itself, which includes your IP address, the name and version of your browser, and the time of the request. That happens before any of this page's code runs, and it is the same for every website you visit. What it does not see is anything you paste, because nothing you paste is ever part of a request. That includes the token itself. It is decoded entirely in this tab and its claims are never sent anywhere, which also means SafePaste has no way to check whether its signature is genuine.

Cookies, storage and tracking

Links to other sites

The footer links to Flytrap Industries and to a Stripe donation page. Neither is contacted unless you click it. They carry no query string and no referrer, so following one tells the destination nothing about what you were doing here. If you do donate, Stripe handles that payment under its own privacy policy and SafePaste never sees your card details.

Working offline

Save this page to disk and open it again. It is a single self-contained file, so it works with no network at all, including on a machine that has never been connected to one.

This policy describes the page you are reading. It is part of the same file, so the copy you save to disk carries it too.

How JWTs work

A JSON Web Token is three chunks of text glued together with dots, in the form header.payload.signature. The header and payload are each just a JSON object, written in base64url so they are safe to put in a URL or an HTTP header. Base64url is an encoding rather than encryption, so anyone holding the token, including this page, can read both of them without a password or a key.

The header says how it was signed

The header usually has two fields. The first, alg, names the signing algorithm, and the second, typ, is almost always the literal string JWT. alg can legally be the string none, which means the token is not signed at all. A responsible server must check that alg is one it actually expects before trusting the token's claims.

The header can also say which key to check the token with. kid is a key ID, which the checker looks up in a set of keys it already trusts, usually a set the issuer publishes. A few other fields, jwk, jku, x5c and x5u, go further and carry the key itself or a web address to fetch it from. A key is not trustworthy just because the token brought it, since anyone can make a key and sign a token with it. It only counts once it is tied to something the checker already trusts, such as a certificate chain that leads to a trusted root, a key address the issuer is known to use, or a key the checker already holds. When any of these fields appear, this page lists them in the summary and explains what each one declares.

The payload carries the claims

The payload holds whatever the issuer wanted to say, which is usually who the token is about, what they are allowed to do, and for how long. RFC 7519 gives a handful of fields a fixed meaning, and this page picks those out and shows them in the summary above the JSON:

exp, nbf and iat are seconds since 1 January 1970, UTC. This page converts them into your own local time so you do not have to.

The signature is the part this page cannot check

Checking a signature proves the header and payload have not changed since they were signed. That is how a server can trust the token, and checking it requires a key. There are two kinds of keys:

So this page shows you the signature's raw bytes and nothing more. A token that decodes cleanly here is not necessarily genuine and should not be treated as such until the signature is verified.

If you need to actually verify a signature, do it with the library your server already uses to check tokens, using the same key it checks them against.