JSON web token format: $HEADER.$PAYLOAD.$SIGNATURE, where each substring is (URL-safe) base64 encoded. These can be passed around as a user cookie, HTTP header, or queried from local storage.

$HEADER and $PAYLOAD are both JSON blobs, but $SIGNATURE is binary data.

  • $HEADER takes the form { "alg": "RS256", "typ": "JWT" }, where alg is a signing algorithm supported by the server.
  • $PAYLOAD is a JSON blob containing various pieces of user information, which can include permissioning data. See jwt.io for a detailed breakdown.
  • $SIGNATURE is the signature (using alg from the $HEADER) of $HEADER.$PAYLOAD (both parts base64 encoded) using a server-side secret (often an SSL key… but sometimes just a string!).

Use basenc (basenc --base64url and basenc -d --base64url) to encode/decode URL-safe base64, rather than the base64 binary. Be sure to strip the trailing = signs!

“None” signature attacks

How to exploit JWTs that support the NONE signature algorithm

Sometimes servers will also support the NONE signature type, which indicates that no signing is used (so the JWT is then just $HEADER.$PAYLOAD. — note the trailing dot!). If the server allows the NONE signing method, then it’s often possible to just arbitrarily edit the $PAYLOAD to gain access to other users.

The base64-encoded version of {"typ":"JWT","alg":"none"} is eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.

Link to original

Public key attacks

How to exploit JWTs signed using a public key

JWT algorithms can use a server’s public key if alg is HS256. If the public half of the keypair used to sign the JWT is available somehow (for example, if it’s been re-used as the server’s HTTPS certificate), then we can harvest it and use it to forge new JWTs.

The base64-encoded version of {"typ":"JWT","alg":"HS256"} is eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9Cg.

Use the following to generate a signature with the above $HEADER and the PEM-formatted $PUBLIC_KEY_FILE half of the public/private key to validate the JWTs (when alg is RS256):

echo -n "$HEADER.$PAYLOAD" | \
openssl dgst -sha256 -mac HMAC -macopt hexkey:$(cat $PUBLIC_KEY_FILE | xxd -p | tr -d '
') | \
sed -e 's/.*= //' | \
tr -d '
' | \
xxd -p -r | \
basenc --base64url | \
sed -e 's/=*$//'
Link to original

Brute-forcing weak secrets

How to brute force weak JWT secrets

If a weak secret (a simple string) is used to sign the JWT token, then it is sometimes possible to brute-force it using JWT-Cracker.

Link to original