JWT Tokens (4)

JWT signing

Each JWT token should at least be signed before sending it to a client, if a token is not signed the client application would be able to change the contents of the token. The signing specifications are defined here the specific algorithms you can use are described here It basically comes down you use "HMAC with SHA-2 Functions" or "Digital Signature with RSASSA-PKCS1-v1_5/ECDSA/RSASSA-PSS" function for signing the token.

Checking the signature

One important step is to verify the signature before performing any other action, let’s try to see some things you need to be aware of before validating the token.


Try to change the token you receive and become an admin user by changing the token and once you are admin reset the votes


⚠️ Lesson used to not turn green on validation, but is confirmed to do so in version M26.

💡 Select a different user and look at the token you receive back, use the delete button to reset the votes count 💡 Decode the token and look at the contents 💡 Change the contents of the token and replace the cookie before sending the request for getting the votes 💡 Change the admin field to true in the token 💡 Submit the token by changing the algorithm to None and remove the signature

  • Open the Development Tools in the browser, and go to the Network tab.

  • Log in as Tom on WebGoat and click on Reset Votes.

  • Locate the query to reset in the Network tab and click on Headers.

  • Notice the header:

Cookie: access_token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1NjQ0MDIyNDQsImFkbWluIjoiZm
  • In base64, this is decoded as: {"alg":"HS512"}.{"Iat":1564402244,"admin":"false","user":"Tom"}.signature.

  • Edit it to {"alg": null}.{"Iat":1564402244,"admin":"true","user":"Tom"}..

  • Re-encode it to base64 (eyJhbGciOiBudWxsfQ.eyJpYXQiOjE1NjQ0MDIyNDQsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.). (Pure base64 encoding might give paddings with '==' which will mess up the jwt library used in WebGoat, this is cleaned up)

  • Click on Modify and Resend, modify the cookie with the newly generated value and send again the request.

Last updated