DEV Community

Serguey Asael Shinder
Serguey Asael Shinder

Posted on

Your Token Tells the Server How to Check It

A signed token comes in three parts.

A header.
A body.
A signature.

The body says who you are.

The signature proves
the server wrote it.

And the header says
which algorithm made the signature.

That last part is the trap.

Many verifiers
read the algorithm from the header,
and then check the signature
the way the header told them to.

So the token
chooses its own test.

The oldest version of the attack
is almost a joke.

Set the algorithm to none.

Remove the signature.

Change the body
to say you are an admin.

A library that trusts the header
looks up how to verify none,
finds that there is nothing to verify,
and lets you in.

The cleverer version
needs no gap in the code at all.

Your server signs with a private key
and checks with a public one.

The public key is public.

It sits on an endpoint
for anyone to download.

Now take that public key,
switch the header
to a shared secret algorithm,
and sign your forged body
using the public key's bytes
as the secret.

A verifier that takes
the algorithm from the token
and the key from its config
will compute the same signature
and call it valid.

Nothing was stolen.

The attacker used the one thing
you were happy to give away.

Both attacks are years old.

Most good libraries now refuse them
by default.

Yours might be an old one,
or a thin wrapper
somebody wrote around one,
or configured with a flag
that put the old behaviour back.

The fix is one decision.

The server says
which algorithm it accepts.

Never the token.

Pin it in the verifier,
one algorithm,
or a short list you chose.

Bind each key to its algorithm,
so a public key
can only ever check
the kind of signature
it was made for.

Reject none
everywhere,
including in tests.

Ignore any header
that points at a key
by URL.

Then attack yourself.

Forge a token with none.

Forge one with the public key
as a secret.

Both should fail
before anything reads the body.

A lock that asks the key
how it would like to be checked
is not a lock.

– Serguey Asael Shinder

Top comments (0)