Open main menu

JSON Web Token (JWT, sometimes pronounced /ɒt/[1]) is an Internet standard for creating JSON-based access tokens that assert some number of claims. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client. The client could then use that token to prove that it is logged in as admin. The tokens are signed by one party's private key (usually the server's), so that both parties (the other already being, by some suitable and trustworthy means, in possession of the corresponding public key) are able to verify that the token is legitimate. The tokens are designed to be compact,[2] URL-safe,[3] and usable especially in a web-browser single-sign-on (SSO) context. JWT claims can be typically used to pass identity of authenticated users between an identity provider and a service provider, or any other type of claims as required by business processes.[4][5]

JSON Web Token
StatusInternet Standard
First publishedDecember 28, 2010 (2010-12-28)
Latest versionRFC 7519
May 2015
OrganizationIETF
AbbreviationJWT

JWT relies on other JSON-based standards: JSON Web Signature and JSON Web Encryption.[1][6][7]

StructureEdit

Header
{
 "alg" : "HS256",
 "typ" : "JWT"
}
Identifies which algorithm is used to generate the signature

HS256 indicates that this token is signed using HMAC-SHA256.

Typical cryptographic algorithms used are HMAC with SHA-256 (HS256) and RSA signature with SHA-256 (RS256). JWA (JSON Web Algorithms) RFC 7518 introduces many more for both authentication and encryption.[8]

Payload
{
 "loggedInAs" : "admin",
 "iat" : 1422779638
}
Contains a set of claims. The JWT specification defines seven Registered Claim Names which are the standard fields commonly included in tokens.[1] Custom claims are usually also included, depending on the purpose of the token.

This example has the standard Issued At Time claim (iat) and a custom claim (loggedInAs).

Signature
HMAC-SHA256(
 base64urlEncoding(header) + '.' +
 base64urlEncoding(payload),
 secret
)
Securely validates the token. The signature is calculated by encoding the header and payload using Base64url Encoding and concatenating the two together with a period separator. That string is then run through the cryptographic algorithm specified in the header, in this case HMAC-SHA256. The Base64url Encoding is similar to base64, but uses different non-alphanumeric characters and omits padding.

The three parts are encoded separately using Base64url Encoding, and concatenated using periods to produce the JWT:

const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)

The above data and the secret of "secretkey" creates the token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI

This resulting token can be easily passed into HTML and HTTP.[3]

UseEdit

In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned and must be saved locally (typically in local or session storage, but cookies can also be used), instead of the traditional approach of creating a session in the server and returning a cookie.

Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. The content of the header might look like the following:

Authorization: Bearer eyJhbGci...<snip>...yu5CSpyHI

This is a stateless authentication mechanism as the user state is never saved in server memory. The server's protected routes will check for a valid JWT in the Authorization header, and if it is present, the user will be allowed to access protected resources. As JWTs are self-contained, all the necessary information is there, reducing the need to query the database multiple times.

Standard fieldsEdit

The Internet drafts define the following standard fields ("claims") that can be used inside a JWT claim set:

code name description
iss Issuer Identifies principal that issued the JWT.
sub Subject Identifies the subject of the JWT.
aud Audience Identifies the recipients that the JWT is intended for. Each principal intended to process the JWT must identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the aud claim when this claim is present, then the JWT must be rejected.
exp Expiration Time Identifies the expiration time on and after which the JWT must not be accepted for processing. The value must be a NumericDate:[9] either an integer or decimal, representing seconds past 1970-01-01 00:00:00Z.
nbf Not Before Identifies the time on which the JWT will start to be accepted for processing. The value must be a NumericDate.
iat Issued at Identifies the time at which the JWT was issued. The value must be a NumericDate.
jti JWT ID Case sensitive unique identifier of the token even among different issuers.

The following fields can be used in authentication headers:

code name description
typ Token type If present, it is recommended to set this to JWT.
cty Content type If nested signing or encryption is employed, it is recommended to set this to JWT; otherwise, omit this field.[1]
alg Message authentication code algorithm The issuer can freely set an algorithm to verify the signature on the token. However, some supported algorithms are insecure.[10]
All other headers introduced by JWS and JWE.[6][7]

ImplementationsEdit

Vulnerabilities and criticismEdit

JSON web tokens may contain session state. But if project requirements allow session invalidation before JWT expiration, services can no longer trust token assertions by the token alone. To validate the session stored in the token is not revoked, token assertions must be checked against a data store. This renders the tokens no longer stateless, undermining the primary advantage of JWTs.[35]

Security consultant Tim McLean reported vulnerabilities in some JWT libraries that used the alg field to incorrectly validate tokens. While these vulnerabilities were patched, McLean suggested deprecating the alg field altogether to prevent similar implementation confusion.[10]

With proper design, developers can address algorithm vulnerabilities by taking precautions:[36][37]

  1. Never let the JWT header alone drive verification
  2. Know the algorithms
  3. Use an appropriate key size

Software security architect Kurt Rodarmer points out additional JWT design vulnerabilities around cryptographic signing keys and a significant vulnerability that exposes a library’s JSON parser to open attack.[38] This is a direct result of choosing JSON to express the token header, and is more difficult to mitigate.

ReferencesEdit

  1. ^ a b c d Jones, Michael B.; Bradley, Bradley; Sakimura, Sakimura (May 2015). JSON Web Token (JWT). IETF. doi:10.17487/RFC7519. ISSN 2070-1721. RFC 7519.
  2. ^ Nickel, Jochen (2016). Mastering Identity and Access Management with Microsoft Azure. p. 84. ISBN 9781785887888. Retrieved July 20, 2018.
  3. ^ a b "JWT.IO - JSON Web Tokens Introduction". jwt.io. Retrieved July 20, 2018.
  4. ^ Sevilleja, Chris. "The Anatomy of a JSON Web Token". Retrieved May 8, 2015.
  5. ^ "Atlassian Connect Documentation". developer.atlassian.com. Retrieved May 8, 2015.
  6. ^ a b "draft-ietf-jose-json-web-signature-41 - JSON Web Signature (JWS)". tools.ietf.org. Retrieved May 8, 2015.
  7. ^ a b "draft-ietf-jose-json-web-encryption-40 - JSON Web Encryption (JWE)". tools.ietf.org. Retrieved May 8, 2015.
  8. ^ "draft-ietf-jose-json-web-algorithms-40 - JSON Web Algorithms (JWA)". tools.ietf.org. Retrieved May 8, 2015.
  9. ^ Jones, Michael B.; Bradley, Bradley; Sakimura, Sakimura (May 2015). ""exp" (Expiration Time) Claim". JSON Web Token (JWT). IETF. sec. 4.1.4. doi:10.17487/RFC7519. ISSN 2070-1721. RFC 7519.
  10. ^ a b McLean, Tim (March 31, 2015). "Critical vulnerabilities in JSON Web Token libraries". Auth0. Retrieved March 29, 2016.
  11. ^ jwt-dotnet on github.com
  12. ^ libjwt on github.com
  13. ^ "liquidz/clj-jwt". GitHub. Retrieved May 7, 2018.
  14. ^ cljwt on github.com
  15. ^ [1] on github.com
  16. ^ "bryanjos/joken". GitHub. Retrieved May 7, 2018.
  17. ^ "dgrijalva/jwt-go". GitHub. Retrieved January 8, 2018.
  18. ^ "jwt: JSON Web Token (JWT) decoding and encoding". Hackage. Retrieved May 7, 2018.
  19. ^ auth0/java-jwt on github.com
  20. ^ "kjur/jsrsasign". GitHub. Retrieved May 7, 2018.
  21. ^ "SkyLothar/lua-resty-jwt". GitHub. Retrieved May 7, 2018.
  22. ^ "jsonwebtoken". npm. Retrieved May 7, 2018.
  23. ^ ocaml-jwt on github.com
  24. ^ Crypt::JWT on cpan.org
  25. ^ lcobucci/jwt on github.com
  26. ^ Egan, Morten (February 7, 2019), GitHub - morten-egan/jwt_ninja: PLSQL Implementation of JSON Web Tokens., retrieved March 14, 2019
  27. ^ "SP3269/posh-jwt". GitHub. Retrieved August 1, 2018.
  28. ^ "jpadilla/pyjwt". GitHub. Retrieved March 21, 2017.
  29. ^ JSON-WebToken on github.com
  30. ^ ruby-jwt on github.com
  31. ^ frank_jwt on github.com
  32. ^ [2] on github.com
  33. ^ jwt-scala on github.com
  34. ^ [3] on github.com
  35. ^ Slootweg, Sven. "Stop using JWT for sessions". joepie91 Ramblings. Retrieved August 1, 2018.
  36. ^ "Common JWT security vulnerabilities and how to avoid them". Retrieved May 14, 2018.
  37. ^ Andreas, Happe. "JWT: Signature vs MAC attacks". snikt.net. Retrieved May 27, 2019.
  38. ^ Rodarmer, Kurt (July 21, 2019). "Obscure JWT Security Vulnerabilities". rodarmer.com. Retrieved July 25, 2019.

External linksEdit