Securing a JWT token - api

In general, JWT has an encoded message with a signature. The signature uses for checking the genuinity of the data. My question is, this signature is for assuring the client about the server, but how server can trust the client? In other words, if a client sends a JWT to the server, how the server can be sure this is the right/authenticated client?
My second question is about JWT's lifetime. I know there is a claim (exp) which can be set to indicate JWT's expiry. But what if the client changes that claim? Should I keep expiry date on the server to make sure the JWT is still valid? Wikipedia says: 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.

Given a JWT, the server knows that the client is legitimate by verifying that the HMAC of the header and payload is equal to the signature. The server has a secret key that it uses when computing the HMAC, so if someone wanted to create a fake JWT with a proper signature, they would need to have access to this key.
Your second question shares the same idea as the first. If a client wanted to change the expiration of their JWT, they would have to recompute the signature, and to do this successfully, they'd have to know the secret key.
The point of using JWTs is not to store data like the expiration date on the server, all of this data lives inside the token itself, and the integrity of this data is protected by the secret key used to compute the signature.

JSON web token (JWT) can come in two flavours. Typical, the most widely used form is to use JWT with a JSON web signature (JWS). In security world, this provide integrity. Other form is JWT with JSON web encryption (JWE). This form provides both integrity and confidentiality.
So if you have a specific requirement to identify that you get a valid, condifential JWT, then you should adopt JWE based approach. You can read more about this in RFC7516. For encryption, you can use either symmetric or asymmetric keys. Once you receive JWE based JWT, you can validate that it was sent by intended party by successful decryption of the JWT payload.

Related

Best practises using JWT for authentication

I have read a lot of articles related to JWT (JSON web token) use for authentication and got really confused, since everyone has a different opinion on what is a secure way of using them. By saying secure I mean handling logouts and password changes. Also, what data should not be saved in JWT payload.
My question - Are there any industry standards when using JWT for Auth, if yes what are they? If not, is it secure to save password hash and logout date in JWT to handle logouts and password changes, if not what are the alternatives?
Are there any industry standards when using JWT for auth, if yes what are they?
First of all, access tokens (as any type of sensitive information) must only be sent over a secure connection.
On my understanding, you want the ability to revoke the tokens when some sort of event occurs. In this case, you should consider keeping the track of tokens somewhere in your server.
To achieve it, you could assign a unique identifier to each token and then store such identifier in your server. When validating the token, besides checking the signature and the expiration date, you must also check whether the token identifier is whitelisted.
And, to assign a unique identifier to each token, you can use the jti claim:
4.1.7. "jti" (JWT ID) Claim
The jti (JWT ID) claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well. The jti claim can be used to prevent the JWT from being replayed. The jti value is a case-sensitive string. Use of this claim is OPTIONAL.
If not, is it secure to save password hash and logout date in JWT to handle logouts and password changes, if not what are the alternatives?
If your JWT is a JWS, you shouldn't put any information that is considered sensitive in the payload.

Auth0: Managing authentication on Lambda functions

Current Implementation
My current application utilizes Vue.js + Auth0 on the frontend.
Vue.js utilizes AWS API Gateway, POST/GET methods are sent via:
https://xxxx.execute-api.us-east-1.amazonaws.com/dev/
On the API Endpoints that require authentication I have a "jwtRsaCustomAuthorizer" Authorizer. Which is documented here.
Remaining Concern
However is validating IF the token is valid enough? In this scenario I want to make a POST function that will do two things:
Update the users app_metadata
Save data associated to user
How do I KNOW User id auth0|123456 is who they say they are?
With the JWT being validated by the Authorizor, do I know the token hasn't been manipulated? E.g. if I just decode the passed data, can I assume the userID is valid?
The short answer is: You do not really care in the frontend. Validation of the token normally happens via the backend, which is in your case through the jwtRsaCustomAuthorizer you were talking about. If the backend trusts the token it returns data, and if it does not it returns an authorisation error.
Your backend, and in particular jwtRsaCustomAuthorizer, does validate that the content of your JWT token is valid and trusted. A JWT token consists of three parts. The first part describes the algorithm used. The second part is the payload, which contains the claims, a nonce, an issuer and an expiration date. The third part is used to verify if the JWT token is issued by a trusted party by using a secret and generating a signature with it. In your case you are using RS256 with a private and public key pair.
Since the first two parts of the JWT token are used to generate the signature, you cannot change the algorithm or the payload without invalidating the signature. Since RS256 uses assymetric encryption using a public and private key pair, you can either verify the JWT token by performing the same steps using the private key and comparing the newly generated signature against the signature in the JWT token, or in case of your api endpoint, using the public key to decrypt the signature and checking that against the first two parts of the JWT token.
jwtRsaCustomAuthorizer ensures that the JWT token was created by auth0 by checking the JWT token against the public key that is provided by auth0. If the signature matches the payload, it means that the issuer must have had access to the private key, which is only available to the issuer. This allows you to trust the payload.
You can find more information via jwt.io and this stackoverflow question on the difference between hs256 and rs256.

JWT - per user signing key

In my project there's a requirement to invalidate all jwt tokens of a user when the user changes his password. I was thinking of giving each user a different signing key, and simply reset the key when password is changed. Then I googled around and found Redis is a good place to store those per-user keys. Everything seems to work just fine.
But there one thing I cannot get my head around. Since it has to hit Redis once per request, is it any different than issuing the user an opaque token instead of JWT, and store the token -> JWT payload mapping in Redis?Isn't that defeats the purpose of using JWT?
To invalidate tokens you need to revoke them. OAuth spec also does not require getting secret key from remote server every time you need to validate JWT (as you said it kind of defeats the purpose). The key can be stored locally at resource site.
You have two options here:
1) Introspect the JWT token from resource side against OAuth server every time it validates it. Seems like overkill to me. The best approach is to give short expiration time to JWT token and let the already issued tokens to just expire.
2) Have the resource store the secret key locally and when it fails to validate go and get the key and re-validate it again.
From the point of view of invalidating the token, there's no particular need to store the JWT in Redis - anything that you can check and later invalidate should do the trick.
That said, presumably you're using a JWT for other reasons. For example, it's what the AuthN/Identity service provides. Or perhaps you use it to store claims or other metadata that you validate as part of the AuthN/AuthZ logic. In that case, since it's handy, storing the JWT seems very reasonable.

Encoding and Decoding API Access token with keys

I am planning to secure my rest API in django with a ACCESS_TOKEN.
When ever user is logged in using their username and password, once they are authenticated, I generate a ACCESS_TOKEN and passed to frontend be it Website or Native application. and then later used that ACCESS_TOKEN for further communication.
I am generating this token based on some user data and then encrypting this with public key. Later when application send this for in any request, I decrypt the ACCESS_TOKEN with private key and extract user data data and process the request. This is something similar to session where session data is in encrypted form in ACCESS_TOKEN and only private key and decrypt the ACCESS_TOKEN. This is what I am planning to do.
Please suggest me for following questions:-
1. Is is the best way to secure my REST API? I want to use my API in same way from Web-application(AJAX calling) and NATIVE application(Android/IOS etc) ?
2. What is the best way to expire the token? Do I need to keep track of access token at my end in order to expire them?
Also I do want to use the Oauth in my API.
Most people I see use JWT's that are signed but not encrypted so they store non-PI data like user_id or session_id. I guess you could encrypt it if needing to store personal information but I don't see any other reason. Assuming you are using HTTPS, then only the end client would have access to the information. Sounds like asking for trouble if the secret gets leaked so you would want a really good key rotation scheme since you may not even know its leaked until too late.
Many people using JWTs do so because they don't want a centralized auth server, thus the token is short lived like a few hours or days. If you need really tight control on expiring tokens, you can take a blacklist approach where a blacklist of JTI's (JWT Ids) are stored in a K/V to be checked against. https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/

REST authentication / authorization

I need some advices on how to secure my application:
I have a REST service, using Spring MVC 3
I have my client application, using Ext GWT 2.2
Users credentials are available on the server side only.
SSL available
REST services should only be used by authentificated users.
I have read about HTTP Digest , token based authorization, oAuth etc, but I need some clarification and advices on how to secure my application, and which methods are the best in my case.
here is the methodology we created for our applications, works very well, and is very secure.
this is a very conceptual explanation, there is a lot of code that backs this up, FYI
When user authenticates or creates account, the server returns an x.509 certificate, base64 encoded, that is unique to for the user. The server stores a copy.
Everytime the client needs to access the REST API, client creates a JSON string comprised of the following.
The Users Unique ID (UserID)
A GUID or UUID, that guarantees this call is unique,(CallID) (protects against replay attacks)
A Dictionary (collection of Key/Value) of each parameter of the rest call
we then encrypt that string with the x.509 public key, and encode it back to base64 string, and take this encrypted value and add the UserID to a json object we call the token.
we then put the token into header of each call, and call it something like: X-Auth-UserToken
On every call the server takes the token, looks up the users certificate based on the userID, then verifies that the encrypted part of the token can be decrypted with the private key that the server holds for the user.
once decrypted, the server takes the CallID and verifies that it is unique, against its own calllog db.
if it checks out, the user is authenticated.
once the user is authenticated, you can apply your own authorization rules based on the users uniqueID.
of course, all the above is over SSL.
let me know if you need me to drill down on any parts.