JWT how does it work and is it secure? (2024)

JWT how does it work and is it secure? (1)

Achraf Affes

Posted on • Updated on

JWT how does it work and is it secure? (3) JWT how does it work and is it secure? (4) JWT how does it work and is it secure? (5) JWT how does it work and is it secure? (6) JWT how does it work and is it secure? (7)

#token #react #jwt #security

JWT stands for JSON web token

the common definition says that it is an open industry standard RFC 7519 method for representing claims securely between two parties

so lets break it up into a simpler logic to understand its utility and the way it works!
So JWT was built by some developers in Microsoft, they built it initially for information exchange, and later on it was repurposed for authorization.

In security processes, authentication validates a user's identity, it also grants that user permission to access a resource.
JWT is a stateless session, so it does not need to be saved in a database in the server-side like cookies, it only exists in the client side.

A JWT is composed by :

header . payload . signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The Header is the metadata about the token, its the result of

const base64Url = require("base64-url") // used for Base64 and URL Encoding Decoding const header = base64Url.encode( JSON.stringify({ alg :"HS256", // algorithm : none, HS256, RS256, PS256 etc .. type :"JWT", ... }));//outputs : eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9

please notice that it is not encrypted it's just encoded which means you can use base64 decode and you will get the JSON object in clear.

the payload contains the message we want to send alongside with different information about the token itself

const base64Url = require("base64-url") // used for Base64 and URL Encoding Decoding const header = base64Url.encode( JSON.stringify({ sub:"1234567890", //subject iss:"Darken", //issuer aud:"My API", //audience used for auth as well  exp:1633895355, //expiration datetime iat:1633895235, //issued at datetime ... }));//outputs : eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9//lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Again it is not encrypted it's just encoded which means you can use base64 decode and you will get the JSON object in clear.
So far we are not securing information, so you may be wondering, how is this secure, and where is the authentication in all of this?
And that's where the signature plays it's role!

A signature is the result of some function that uses the header, the payload a secret key and hash function.
The secret key is the most important part, a good advice is to use a 256bit key and don't hard code it ( save it in process.env )
Please note that if we are using asymmetric encryption, when calculating the signature the algorithm uses both keys ( private and public )

So the signature is usually calculated like this :

const crypto = require("crypto") // cryptography libraryconst base64Url = require("base64-url") const secret = process.env.SECRET//Again ! please use a 256bit secret keyconst content = "${header}.${payload}"//used for Base64 and URL Encoding Decoding const signature = base64Url.escape( crypto.createHmac('sha256',secret) .update(content) .digest('base64'));//outputs : SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Now this creates an HMAC encryption (Hash-based message authentication code) a cryptographic technique that combines the key and a hash into a mix hackers can't unpack.

So the authentication part shows up here! Have the content of this message been manipulated?

Remember that the token is equal to :

const token = "${header}.${payload}.${signature}"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Since the hacker can change the signature but can't guess the right signature( he doesn't know the secret key ) then when the attacker changes the payload or the header, the signature no longer matches the data.
So lets suppose the hacker decoded the payload and changed it to :

{ "sub": "This was changed", "name": "AchrafAffes", "iat": 1516239022}//The payload encoded will then be changed to :eyJzdWIiOiJUaGlzIHdhcyBjaGFuZ2VkIiwibmFtZSI6IkFjaHJhZkFmZmVzIiwiaWF0IjoxNTE2MjM5MDIyfQ

And again! since the hacker can't guess the right signature for the new encoded payload ( no secret key ) then when the server decodes the header and the payload, and recalculates the new signature it will be : do3cSS2wLRUM6cmqVqvFZVpCwJkeO0BieF0h0oTWaBE
which is impossible for the hacker to guess unless he knows the secret key ( remember when using single symmetrical key to use a 256 bit key) and here the server will predict that the payload or the header were changed and therefore it will ignore the request.

Now that you understand how the JWT works, how do we use it in action ?

For me I use it as following, the user logs in, the server checks for the credentials whether this user coords exists or not, if it does, the server generates a token and sends it to the user ( the server does not save a copy ) the user then saves the token in its localstorage ( the token should have a short expiration datetime since it is vulnerable for XSS attacks which I'll explain in another post in the future )
Whenever the user wants to access something, it sends the token in its header, and the server verifies it, if its verified then the server responds else the server responds with a 403 Forbidden error.

In some other solutions, we implement an authentication server(AS), the user passes by the AS first and then it is redirected to the resource server (API) which will verify the token with each request.

If you are working with nodeJs you can use the jsonwebtoken package, to easily implement the JWT

var jwt = require('jsonwebtoken');const secret = 'secretkey'//please make sure to use a 265bit keyconst data= {username:"achraf",other:"stuffHere"}//to generate the data we uselet token = jwt.sign( data, secret, {expiresIn : '2 min'} //other options can be used);//and to verify it you can usejwt.verify(token,secret, function(err, tokendata){ if(err){ console.log("Unauthorized request") } if(tokendata){ console.log("verified") }})

so lets talk quickly about the most recommended algorithms that can be used :

HS256 : HMAC + SHA-265
(relies on the shared symmetrical key)

RS256 / RSASSA + SHA-256
(relies on private/public RSA key pair, but it may overload the network and uses more CPU for calculation )

ES256 : ECDSA using p-265 and SHA-265
(relies on private/public RSA key pair but much shorter )

I'll try to talk about these algorithms in details in the future

finally I wanna talk about the difference between cookies and JWT:

  1. Cookies need to be stored on the server-side while JWT are stateless
  2. since cookies require a database, this database will be queried on each client request
  3. cookies are vulnerable for both CSRF and XSS attacks, while JWT is only vulnerable to XSS attack.

Top comments (5)

Subscribe

Thomas Broyer

Thomas Broyer

Developer and architect mainly interested in web development (frontend, Web APIs), web app security, build tools, Java, Kotlin, Gradle, etc.

  • Location

    Dijon, France

  • Joined

Oct 13 '21 • Edited on Oct 13 • Edited

  • Copy link

About the conclusion of the article:

  • while cookies can be abused from XSS (e.g. session fixation with a cookie set from JS), they can't be exfiltrated if correctly used (with the HttpOnly flag), whereas your JWT in localStorage can be read by any JS, making XSS a much higher risk (well, in any case, if you have an XSS, it's gameover, unless maybe you actually only keep things in a non-global variable, i.e. not localStorage)
  • if you stored a session ID in localStorage, you'd mitigate CSRF the same
  • if you stored a JWT in a cookie, you'd be vulnerable to CSRF the same

It's not about what you use to authenticate your user, it's about how you put it.

Also, you're not tackling logout, aka revoking your JWT. To do that, you'll need to store things server-side and querying them on each client request. If your JWT tokens have a very short expiration (like the 2 minutes in your sample code), this is OK, but this will negatively impact UX (having to sign in again every 2 minutes) or security (keeping the user credentials in memory client-side).

About that sample code, you're not putting the user's password in the JWT are you ‽

About JWTs themselves, you can make an equivalent system (cryptographically sign, or encrypt by the way, some data that you also base64-encode) without the drawbacks of JWT (signature details "negotiation" through the JWT header).

Some reading about JWTs:

That last article also tackles the "accessing the database issue":

I continue to believe that boring, trustworthy random tokens are underrated, and that people burn a lot of complexity chasing statelessness they can't achieve and won't need, because token databases for most systems outside of Facebook aren't hard to scale.

Achraf Affes

Achraf Affes

telecommunication and computer science engineerhttps://github.com/Achraf513https://www.linkedin.com/in/achraf-affes

  • Location

    Tunisia Ariana

  • Education

    SupCom

  • Work

    Student

  • Joined

Oct 13 '21

  • Copy link

Thanks a lot for sharing your knowledge about the subject,
thanks for articles as well,

The post was a general presentation about JWT and the way it works and the main practices to make it more secure ( I admit as well that storing it in localStorage is risky unless we use short expiration time, which in some cases ruins the user experience )

I believe that using tokens vs cookies will always last as a huge debate, yet I admit that in some implementations, its better to use cookies over tokens for better user experience as you said.

Thanks again for sharing your knowledge about the subject.

Brent Dalling

Brent Dalling

Software Developer. Coffee Drinker. Mountain Biker. Office Chair Gravity Tester. Photo Taker. Human Being?

  • Location

    Dallas, TX

  • Education

    Western Governors University

  • Pronouns

    He/Him

  • Work

    Software Engineer at Sparkfish LLC

  • Joined

Oct 22 '21 • Edited on Oct 22 • Edited

  • Copy link

Couldn't you interpret the original requester IP and place it into the JWT? If the JWT signs the contents, to later verify the contents, couldn't you prevent session hijacking? Otherwise, simply storing the JWT in cookies or localstorage could result in an attacker stealing the JWT.

JWT is something I want to learn more about. Please let me know if I am missing something! Great article!

Achraf Affes

Achraf Affes

telecommunication and computer science engineerhttps://github.com/Achraf513https://www.linkedin.com/in/achraf-affes

  • Location

    Tunisia Ariana

  • Education

    SupCom

  • Work

    Student

  • Joined

Oct 22 '21

  • Copy link

Thanks Brent, well to be honest, I didn't test it as a solution, yet I read about it in many articles, the idea seems to solve the problem, in fact some solutions tend to use IP address and the UserAgent of the client.

I currently started studying cyber security, and I can tell you that nothing, and I mean literally NOTHING is unhackable... ( IP addresses can be spoofed )
it's simply about trying to make things safer harder to break through.

Brent Dalling

Brent Dalling

Software Developer. Coffee Drinker. Mountain Biker. Office Chair Gravity Tester. Photo Taker. Human Being?

  • Location

    Dallas, TX

  • Education

    Western Governors University

  • Pronouns

    He/Him

  • Work

    Software Engineer at Sparkfish LLC

  • Joined

Oct 26 '21

  • Copy link

Thanks for the honest reply. I honestly think that rotating the session often and logging IP's/user-agents/domains is the best way to prevent piggybacking or session hijacking. Ip addresses and domains can be faked. However, over the open web this can be quite difficult (in peer to peer communications such as API's). Rotating would invalidate any stolen sessions before they could be used. The IP logging could be used to determine if access is coming from an unknown address and trigger a 2FA response. The domain would be useful for API based authentication (peer to peer).

For further actions, you may consider blocking this person and/or reporting abuse

JWT how does it work and is it secure? (2024)

FAQs

JWT how does it work and is it secure? ›

Information exchange: JWTs are a good way of securely transmitting information between parties because they can be signed, which means you can be certain that the senders are who they say they are. Additionally, the structure of a JWT allows you to verify that the content hasn't been tampered with.

How secure are JWT claims? ›

Don't Trust All the Claims

Claims in a JWT represent pieces of information asserted by the authorization server. The token is usually signed, so its recipient can verify the signature and thus trust the values of the payload's claims. You should be wary, however, when dealing with some claims in the token's header.

Is JWT secure over https? ›

HTTPS encrypts the communication between the browser and the server, preventing anyone from intercepting or tampering with your JWT tokens. Without HTTPS, your tokens are vulnerable to man-in-the-middle attacks, replay attacks, or eavesdropping.

Is JWT encrypted or not? ›

JSON Web Tokens (JWT) are commonly used in many different applications which require some sort of cryptographic primitive. Most often, the JSON Web Signature (JWS) structure is chosen as its contents are signed and not encrypted; however, the JSON Web Encryption (JWE) structure may also be used to make a JWT.

Is JWT secure for authentication or authorization? ›

JWTs can be used as an authentication mechanism that does not require a database. The server can avoid using a database because the data store in the JWT sent to the client is safe.

What is the weakness of JWT? ›

When designing the JWT implementation, one must select an algorithm to use. Choosing a symmetric algorithm is weaker as anyone knowing the secret can create or validate a token. If the secret is known, an attacker can forge a token with an arbitrary set of claims.

Why JWTs are bad for authentication? ›

Because JWTs are frequently not encrypted, anyone who can execute a man-in-the-middle attack and sniff the JWT now has access to your authentication credentials. This is made easier because the MITM attack only has to be carried out on the server-client connection.

Is it safe to store email in JWT? ›

Yes, it is bad practice and a security problem.

Email addresses are PII (personally identifiable information). Like all other PII, email addresses should never be stored unencrypted at rest; doing so is inherently insecure.

Is JWT vulnerable? ›

As JWTs are most commonly used in authentication, session management, and access control mechanisms, these vulnerabilities can potentially compromise the entire website and its users.

Is JWT best for authentication? ›

JWT is a common way of implementing authentication in web and mobile apps. Read more to know how you can use JWT and learn the necessary best practices. One of the most used authentication standards in web applications is the JSON Web Token standard.

Can someone steal JWT? ›

JWT tokens provide secure access to an authenticated user, and attackers are always looking for ways to steal these tokens and quickly gain access by impersonating a consumer.

What is more secure than JWT? ›

Secure: Opaque tokens do not contain any user information, making them more secure than JWT tokens.

Why avoid JWT? ›

JWTs which just store a simple session token are inefficient and less flexible than a regular session cookie, and don't gain you any advantage. The JWT specification itself is not trusted by security experts.

Can JWT be intercepted? ›

Because JWTs are used to identify the client, if one is stolen or compromised, the attacker has full access to the user's account in the same way they would if the attacker had compromised the user's username and password instead.

How much JWT is secure? ›

JWT can be encrypted with AES which is fast and supersecure. If the server can decrypt it, it means the server is the one who encrypted it. Summary: non-encrypted JWT is not secure.

What is the difference between JWT and TLS? ›

TLS Mutual Authentication

The difference between the two approaches is, in JWT-based authentication, the JWS can carry both the end user identity as well as the upstream service identity. With TLS mutual authentication, the end user identity has to be passed at the application level.

Can JWT tokens be stolen? ›

JWT tokens provide secure access to an authenticated user, and attackers are always looking for ways to steal these tokens and quickly gain access by impersonating a consumer.

Is JWT vulnerable to XSS? ›

There is 2 way to store JWT in frontend: a. Store it in localStorage b. Store it in Cookie For (a.), It is CSRF safe but is vulnerable to XSS.

Top Articles
Latest Posts
Article information

Author: Rueben Jacobs

Last Updated:

Views: 6375

Rating: 4.7 / 5 (77 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Rueben Jacobs

Birthday: 1999-03-14

Address: 951 Caterina Walk, Schambergerside, CA 67667-0896

Phone: +6881806848632

Job: Internal Education Planner

Hobby: Candle making, Cabaret, Poi, Gambling, Rock climbing, Wood carving, Computer programming

Introduction: My name is Rueben Jacobs, I am a cooperative, beautiful, kind, comfortable, glamorous, open, magnificent person who loves writing and wants to share my knowledge and understanding with you.