JWT Security Check · comparison

JWT Security Check vs. eyeballing the payload

Pasting the two segments into a base64 decoder and reading the resulting JSON genuinely catches an obviously wrong claim value. This page names no specific decoder site or library — decoding a token and reading it by eye is a habit most developers already have, not a competing tool.

What eyeballing the decoded claims catches reliably

A claim that is obviously the wrong value, a typo'd field name, a role or permission that plainly should not be there — anything that looks wrong once you can read the JSON is exactly what a careful reviewer is good at noticing. This tool does not replace that kind of reading.

What eyeballing the decoded claims cannot catch, by construction

CaseReading it decoded, by eyeThis tool
"alg": "none"A real, spec-defined field value — reads as an ordinary field, not an error, unless you already know to distrust it on sightFlags it as high severity every time, with the specific consequence named: a verifier accepting it skips signature verification entirely
An embedded jwk, or a jku/x5u key URL, in the headerDecodes to well-formed JSON — a key object or a URL string, exactly as the spec describes; nothing about the decoded value itself signals riskNames the specific header-injection attack surface each field creates if the verifier trusts it uncritically
A symmetric algorithm alongside an embedded asymmetric key hintTwo separate, individually ordinary-looking fields; recognizing the combination as the documented "algorithm confusion" shape takes knowing to look for itFlags the combination specifically, by name, with the mechanism explained
A kid value shaped like ../../etc/passwd or 1' OR '1'='1Decodes to an ordinary-looking string; nothing marks it as a path-traversal or SQL-injection shape rather than a normal opaque identifierPattern-matches the value against both shapes and names which one it resembles
An excessively long lifetime (exp minus iat)Both are just numbers — recognizing "40 days" as unusually long for an access token requires doing the subtraction and knowing a reference point to compare it againstComputes the lifetime and flags it against a stated, documented reference point

The gap that matters most: the risk lives in the verifying code, not in the decoded text

This isn't a case of a reviewer missing something a more careful read could have caught. Every field above decodes to perfectly well-formed, ordinary-looking JSON — that is exactly what makes each one easy to miss. Whether alg: none is actually dangerous, whether an embedded jwk is actually trusted, whether a long lifetime is actually a problem: all of that depends on code you cannot see by decoding the token, which is the verifying service's own logic. A mechanical check against the exact list of documented patterns, rather than a read of whether the values look plausible, is not a more careful version of reading the payload; it is a different question asked of the same text.

When to still read the decoded claims yourself

This tool only reports the specific patterns on its list, in the header and payload you paste. It is not a security audit, it never verifies a signature, and it never sees your server's verification code — so it cannot tell you whether a jwk header is actually trusted, or whether a role claim is the right one for this user. Judging whether the token's actual business content is correct is still a job for reading the decoded claims yourself.

Common questions

What does eyeballing a decoded JWT actually catch?

A reviewer catches what looks obviously wrong once decoded: a claim value that is clearly the wrong user, a typo'd field name, a role that should not be there. Those are real problems and a careful read finds them the same way it always has. This tool does not replace that kind of reading -- it looks for a narrower, more specific class of problem that decoding alone does not surface.

Why doesn't alg: none look wrong when you read it?

Because "none" is a real, spec-defined value (RFC 7518) for an explicitly unsigned token -- it reads as a normal field with a normal-looking value, not as an error. The problem is not that the field looks malformed; it is that a verifier accepting this value skips signature verification entirely, and that consequence lives in the verifying code, not in anything visible in the decoded header.

Why doesn't an embedded jwk or jku header look wrong?

A jwk (embedded key) or jku (key URL) field decodes to perfectly well-formed JSON -- a key object or a URL string, exactly as the spec describes. Nothing about the decoded value itself signals danger. The risk is entirely about what the verifying code does with it: whether it trusts a key the token itself supplied instead of only its own configured key store, which a read of the decoded JSON cannot tell you either way.

Why is a kid header injection shape easy to miss by eye?

A kid value like "../../etc/passwd" or "1' OR '1'='1" decodes to a completely ordinary-looking JSON string. Recognizing it as a path-traversal or SQL-injection shape requires knowing those specific patterns and actively checking for them -- a plain read-through of the claims, focused on whether the data looks right, has no reason to flag a string field for its shape rather than its content.

Does a clean check mean the token and its verifier are secure?

No. This tool only reports the specific, named patterns it checks for in the header and payload you paste. It never verifies a signature and never sees your server's verification code, so a clean result means none of its checks fired -- not that the token or the service issuing or verifying it is secure.

Check a token