How to prevent faking value of localStorage and login - javascript

I am working on an authentication system, implemented the front end using vuejs and back end with nodejs. User is able to register and login successfully. I am verifying user is logged in using jwt token. My problem is anyone can login by manipulating the localStorage jwt token value. Is there anyway to prevent it.

You should be using an asymmetric signature on your JWT token, and the private key should be available only to the server that creates the JWT. If this is the case, then it's highly unlikely that a user would be able to forge JWT claims.

Here's a step by step of how your server should prevent someone from changing their JWT info:
Your NodeJS server creates a new JWT using an encryption key (we'll call it secret-key) to create the signature, and it sends the token to the client.
The user decides they want admin access, so they change their permissions in their local JWT and send it to the server.
The NodeJS server re-signs the header and payload of the user's JWT using secret-key and compares that generated signature with the signature in the user's JWT. If they match, then nothing has changed about the user's JWT. If they don't match, then either the user changed something in the header or payload, or they tried re-signing the token with their own encryption key. Either way, your server can tell that the JWT isn't valid, and you can deny them access.

Related

JWT token validation on each request?

I have developed a simple bakend server in node with jwt authentication, but I still have a question: after the user has correctly logged in and saved the token in the client side should the server validate the token at every user request? For example when accessing the /profile route (which takes the user to the profile page), or when for example the user creates a question by sending a post request to /posts/create route should I use the method jwt.verify(...) to check if the token is correct everytime? Is it correct also to send the jwt access token instead of the refresh token or is this a bad practice?
Yes, you should validate each request. That is call middleware. In the first step, you check authentication. After that, you can use it for authorization. You can write role, some permission, or other info in JWT.

Whats the best practice for storing Basic Auth password?

Let's say I'm trying to build a web application using Vue.js where an end user uses a form to subscribe to a newsletter.
The frontend is a Vue app, the backend is a PHP REST API.
The API requires Basic Auth authentication.
In the frontend I'm calling the API using axios:
axios
.post('localhost/api/v1/subscriber.php', {
// I know the data is missing but this is not what the question is about..
auth: {
username: 'USER',
password: 'PASS'
}
})
Everything is working fine, except that Vue.js is JavaScript and therefore visible on the client side (right click -> Inspect/ View page source) and every end user can see the username and password.
What's the best practice for "storing" the password (and username)?
Even if PASS was the hashed password, the end user would still be able to use it to to an API call by himself...
From my point of view you have a fundamental design issue with your API. As it seems you want to expose some global credentials to the frontend so the SPA can in turn authenticate against the API. This approach is strange: either the endpoint is public and therefore should not need authentication or it is protected and each user should authenticate properly.
If you just want to protect the API against spam bots etc. you could send a nonce to the app and check for it in the subsequent request. This by no means is a robust protection but makes sure that each POST requires a GET and some parsing on the spammer's side.
If you want your users to be authenticated across multiple requests you should use well established methods to provide a session or a remember-me function. This could be e.g. session cookies (works but is vulnerable against CSRF attacks), JWT (with or without OAuth) or something similar.
But whatever you do: don't try to obfuscate shared credentials you pass around!
As a best practice, you shouldn't store password. You should create a JWT token on the backend when the user logged in or signed up. Then you can store the JWT token on your front-end(local storage) when you received the token from the back-end.
Easy Way to Encryption,
You can encrypt your password with any encryption algorithm on client-side then decrypt on the back-end with the same key.
Hard Way to Encryption,
As a hard way, for security reasons and security best practices, you should encrypt all your request end to end. Otherwise, anyone can access the user's information on public networks.
The below link includes all detailed information about the end to end encryption
https://medium.com/#weblab_tech/encrypted-client-server-communication-protection-of-privacy-and-integrity-with-aes-and-rsa-in-c7b180fe614e
You can store your Authorization header values in localStorage or sessionStorage.
Use interceptors to include the header values for each of your request
Here is sample:
axiosInstance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
config.headers.Authorization = token
return config;
});
The value of Authorization header, stored in LocalStorage, will be automatically each time you make HTTP requests.
Note: Replace the variable token with username and password

How does JWT do Authentication

JWT official docs say that JWT is most commonly used for Authentication.
Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be.
Now if my server gets a request from the client and header of that request contains JWT. I will validate the JWT token with my secret key.
If the token is valid, I can say for sure that:
That token was generated by my server.
At the time of generating token user had provided their correct credentials. Meaning, if user claimed to be John123, they provided correct password for John123 (server verified this, otherwise server return error response).
If the token is valid, what I can NOT say for sure:
On subsequent requests, if the user is claiming to John123 (by passing {userid:John123} in request body) and they provide us with valid JWT, I can't say for sure that their claim is correct. Because its possible that user Alice123 went into the localstorage of John123 and stole the token and set it into their localstorage.
Now my question is how does JWT really validate that the users actually are what they are claiming to be. What I am missing here? Do I need to keep a mapping of JWT, userid and ip of client.
Well one step you are missing is that even after verifying the authenticity and claims (e.g. expiration date) of an incoming JWT, you still probably would have to hit your user database to make sure that the account is active and still exists. So a JWT does not by itself solve the entire problem.
Regarding your actual question at the end, you generally have no idea about who the bearer of the JWT really is. If Alice steals John's phone, then in fact she may be able to masquerade as him. But keep in mind, if she does something this drastic, then she probably also has his credit and bank cards, and maybe some other passwords too. No authentication process is completely safe.
With regard to lesser forms of theft, JWT is still robust. For example, if someone tries to setup a man-in-the-middle attack to sniff your JWT, it won't work assuming your app encrypts that JWT with SSL. And the real reason for JWT of course is that they are already signed with a key only known by the server to prevent the bearers from tampering with them.
JWT does not validate if the users are what they claim to be, because JWT is not an authentication framework. If you use JWT as an access token, you/your authentication middleware should make sure only to rely on the information in the token itself to identify the user and not any information in the request body.
Ususally you would store the user id or name in the token. The subclaim can be used for that.
The "sub" (subject) claim identifies the principal that is the
subject of the JWT. The claims in a JWT are normally statements
about the subject.
The authentication middleware ususally only verifies, that the JWT itself has not been modified. But you won't recognize if Alice uses John's token.

How to use a JWT token as login validation?

I'm making a login page and I've found that JWT tokens are preferred over sessions but I don't understand what to do with a token.
I send user and password uncrypted with ajax to server and validate the user in a php file which then returns a JWT.
What should I put in my JWT? Do I only check for a token to know if the user is logged in or do I process it somehow to check if it's the right token? If so, how?
So far I've seen examples on client side where you only check if token exists but why should I have hashed data as token instead of a 1 or a 0. I don't get the advantages of this method.
EDIT: Should I both request a JWT token which I store in session storage and store what the user types in the log in field also in session storage and then compare them with eachother every time the user reloads the page?
Looks like we need basics of how JWT works here:
The client sends username/password to the server using ajax.
The server checks username/password and if they are valid, creates an encrypted token, which the only server can read and understand.
Server takes into account various fields (also known as "Claims") like "iss" (token issuer) and "Sub" (Subject of token), whole list here.
We can custom fields like user-id which can be used later while validating token.
Server sends token back to client through response. Client saves this token in local storage or some variable.
With each further request, client sends this token as header.
Server examines and validates this token, gets require info from this token like user-id and responds to the user appropriately if valid. Token may also contain expiry date/time, so after a certain time, the server may choose to refuse to serve a client.
While this may not directly answer your question, it clarifies basic workflow of GWT.

Angularjs validate JWT

I have tried implementing JWT to my Angularjs application for a secured authentication. I have generated the JWT at server side(java) and the implementation returns a JWT to the client side after a successful login. I have stored the JWT in $http.defaults.headers.common.Authorization and also in the $window.sessionStorage. Now I could see the JWT in all all requests made by the $http service.
The part I am not clear is I dont know how to proceed from this point. What I guess is I should validate the JWT from now on for all $http calls at the server side somehow. Can someone clarify me how I should proceed for validating the client side JWT at the server side ?
Yes every time the client makes a request to the backend, you now have to supply the JWT in the header.
Inside the JWT you can have some parameters that identifies the user, like his username for example. Do not store password or other sensitive information inside the JWT.
If you are useing Java, you could create a Filter that will be mapped to a url that only an authorized user can have acces. In the filter you can make the necessary checks to see if the suplied token is correct, if it is you can let the request pass trough, otherwise you can return to the client an error specifying that he does not have access.
If you need more information, may be this is a good place to start.

Categories

Resources