What is JWT?
JWT token is a base64url encoded string that is used to transmit the information between server and client. JWT token mostly contains the user information which is used for authorization.
JWT token can be sent through a URL, POST parameter, and HTTP header.
The information that is sent by JWT is verified and trusted because it is digitally signed.
JWT token looks like:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT token has three parts:
https://jwt.io/
Header:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{“alg”: “HS256”,”typ”: “JWT”}
Payload:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
{“sub”: “1234567890”,”name”: “John Doe”,”iat”: 1516239022}
Signature:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HMACSHA256(base64UrlEncode(header) + “.” +base64UrlEncode(payload), your-secret)
Uses of JWT token
* Authorization: After successful authentication, the application receives the JWT token. That JWT token is passed in every request for accessing the services.
* The JWT token is also used for exchanging information.
Why do we need JWT token?
As we know that HTTP is a stateless protocol, for accessing the services we need to authenticate again and again, which is a problem, so the solution for this is the session. The server store sessions for each user, when the user tries to access any service, the application sends the session ID which the server check and provide access if that user is authorized to access that service.
But there is a problem with this scenario. As the Internet is growing nowadays, we are using many APIs for everything. So maintaining a session at the server end for authorization purposes need vertical scaling and horizontal scaling. Which needs hardware. So for this solution, a JWT token was introduced, which contains the user's information for authorization.
Where JWT tokens should be stored?
We have three options for storing the data in the browser:
1. Cookie (CSRF and XSS mitigation should be applied)
2. Local Storage
3. Session Storage
Each of those has its own advantage and disadvantage. For more details please check: https://dev.to/gkoniaris/how-to-securely-store-jwt-tokens-51cf
JWT token has two formats:
JWS: JSON Web Signature
JWE: JSON Web Encryption
So JWT can be in JWS format or JWE format, it depends on what you want to achieve.
JWS: JSON Web Signature
It provides integrity by using signature but doesn't provide confidentiality.
JWE: JSON Web Encryption
It provides both integrity and confidentiality by using both signature and encryption.
How to identify whether the token is JWS or JWE?
- If the “enc” parameter exists in the header then it's JWE otherwise it is JWS.
- Check the algorithm (alg) parameter value. If the value represents a digital signature or MAC algorithm or is the value “none”, it is for a JWS.
If it represents a Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, or Direct Encryption algorithm, it is for a JWE.
Example:
JWS (signed)
{
“alg”: “HS256”
}
JWE (encrypted)
{
“alg”:”RSA1_5",
“enc”:”A256GCM”,
“iv”:”__79_Pv6-fg”,
“x5t”:”7noOPq-hJ1_hCnvWh6IeYI2w9Q0"
}
The basic sequence of getting tokens is as follows:
- A client sends a username/password combination to the server.
- The server validates the authentication.
- If authentication is successful, the server creates a JWT token and refresh token else establishes an error response.
- On successful authentication, the client gets a JWT token in the response body and a refresh token in the cookie with all cookie protection flags like (httpOnly, secure=true, and SameSite=strict flag [whenever possible to prevent CSRF]).
- The client stores the access token in-memory. It means that you put this access token in a variable in your front-end site (like const accessToken = xyz). Yes, this means that the access token will be gone if the user switches tabs or refreshes the site. That’s why we have the refresh token. We’re not putting this access token in localStorage or cookie via JavaScript because it’s easier for attackers to dump that data, making it more prone to be stolen via an XSS attack. We can also use the access token in cookies with all secure flags, but the problem is that the access token is mostly big in size and the cookie size limit is 4kb. Check this blog.
- From next time, the client for making any request supplies the JWT token in request headers like this. Authorization: Bearer <jwt_token>
The server, upon receiving the JWT validates it and sends the successful response else error.
What is a refresh token and why do we need that?
In general, there are two types of tokens: an access token and a refresh token. The access token is used for making API calls to the server. Access tokens have a limited life span, that’s where the refresh token comes in. Once the access token is no longer valid a request can be made to the server to get a new access token by presenting the refresh token. The refresh token can expire but their life span is much longer. This solves the problem of a user having to authenticate again with their credentials. Whether you should use a refresh token or an access token depends.
The refresh token is a random string that the server can keep track of (in memory or stored in a database) in order to match the refresh token to the user the refresh token was granted to.
Check this blog for more details:
https://datatracker.ietf.org/doc/html/rfc6749
https://www.hostnextra.com/kb/json-web-token-refreshing-a-token/
https://stackoverflow.com/questions/27726066/jwt-refresh-token-flow
Copied from: https://stackoverflow.com/questions/27726066/jwt-refresh-token-flow
(A) The client requests an access token by authenticating with the authorization server.
(B) The authorization server authenticates the client and issues an access token and a refresh token.
(C ) The client makes a protected resource request to the resource server by presenting the access token.
(D) The resource server validates the access token, and if valid, serves the request.
(E) Steps (C )and (D) repeat until the access token expires. If the client knows the access token expired, it skips to step (G); otherwise, it makes another protected resource request.
(F) Since the access token is invalid, the resource server returns an invalid token error.
(G) The client requests a new access token by authenticating with the authorization server and presenting the refresh token. The client authentication requirements are based on the client type and on the authorization server policies.
(H) The authorization server authenticates the client and validates the refresh token, and if valid, issues a new access token (and, optionally, a new refresh token).
Before going to the exploitation part, below are the short summary points:
- JWT is Json web token
- JWT is used for authorization and data transfer.
- JWT has 3 parts Header, payload, and signature and all are base64url encoded.
- The header is where “age” and type are defined
{
“alg”: “HS256”,
“typ”: “JWT”
} - The payload is where data are defined which is needed to transfer.
{
“sub”: “1234567890”,
“name”: “John Doe”,
“admin”: true
} - A signature, where the signature is stored of the header and payload.
- JWT mostly used in Authorization: Bearer <token>
- JWT token is mostly used in API authorization
- JWT has two format, JWS and JWE
- JWS = JSON web signature
- JWE = JSON web encryption
- In JWT token itself contains the data and there is no need to store the value on the server-side while in session the value is stored on the server-side and every time it is matched before giving any authorization of the resource.
- When you login into the application after the valid authentication, the authorization token is created and sent to the client for further authorization of resources.
- If we use an authorization bearer token, then the CSRF issue is removed because your script needs to explicitly attach the token to the request and cannot be used cross-domain (unlike cookies).
- If the “enc” value exists in the header it is JWE otherwise it's JWS.
- We can store JWT tokens in Cookie, local storage, and session storage.
- All the storages are accessible by javascript.
- For accessing local storage we need to specify the key value. <script>alert(localStorage.getItem(‘key’))</script> or we can use JSON. Stringify This will convert all of the localStorage contents into a string and overcome this barrier, as an example: <script>alert(JSON.stringify(localStorage))</script>
- There is no mechanism for protecting local and session storage like HTTPonly cookie.
- We can use the JWT token in cookies by using all secure cookie flags like httponly, and secure but cookies have a size limit of 4KB. Therefore, if you’re using a big JWT Token, storing it in the cookie is not an option.
- Refresh Token is usually long-lived opaque strings that are stored in your database and used to get a new access token when the access token expires.
JWT Debuggers:
https://jwt.io/
https://token.dev/
Comments
Post a Comment