Do I need to verify jwt? - javascript

So here is my scenario , I generated a jwt token and stored that token in redis with 1 hour TTL.
Now I see most of tutorials use jwt.verify to verify the token..
I know they are verifying the token is authentic or not
Why I need to use jwt.verify.. Why can't I use redis.exists to check the token is authentic or not..
Most of them say, we can use jwt main feature is no need to use db to check the user and expiration..
But in my scenario I cant store everything in token.. So I am using redis to store the token with session information.
Questions are
1. So I should not use jwt for this kind of scenario.
2. Can I skip jwt.verify?
I am a node newbie..

JWTs can help you quickly retrieve information about the caller, without hitting a database (redis is also a database).
When using JWTs used by client applications/external services you must always verify them to make sure that you are the one that generated them and they have not been tampered with.
Common info stored in the JWT are things like username, real name, group etc. In your scenario, you could use the JWT to store a redis key that holds the info that you want. It might be the case that you always will hit redis to get the info you want, so JWTs don't add a lot of value to your case, but it might be so that you could use JWTs to write smarter code that will only hit redis under certain circumstances eg. if the user has this right, or if we have stored something in redis about this user or not (missing redis key from the JWT token)
You are the only one that can evaluate your scenario and the usefulness of JWTs but don't be hasty to dismiss them, as they provide a nice perfomance/security improvement out of the box.

Assuming that the Redis server is secured and you generate the JWT yourself (as seems to be the case here), you don't need to verify it. Once created, stored it in the cache and retrieve it later you don't need to verify it again because you know it could not have been tampered with in the Redis cache.
Only when receiving JWTs that are generated by 3rd parties you would need to verify that they are authentic.
If on the other hand you are distributing JWTs to 3rd-party applications and clients that you don't control then you will have to make sure that once you they are replayed back to you, they are untampered with by verifying the signature (or do a binary compare against the one stored in the Redis cache) and (when in use) checking the expiry timestamp in the exp claim.

Without any verification in place, it will be possible for a 3rd party to send requests to your API and in most cases the requests will likely turn into a man-in-the-middle attack. It's good security practice to keep a record of all the tokens generated on the server and then authenticate against them with each incoming request.

Related

How should I encrypt passwords for API access without showing off the algorithm to the client?

I have a REST API (.net) which for the initial login requires the password to be encrypted (RSA with OAEP). The reason was to obscure the users passwords from local logs.
Performing this encryption with javascript is complicated and I would need to let the client know the public key. The end user would be able to reverse engineer the encryption method then could use it to brute-force (or worse) access. So why bother, right (it is SSL Secure).
Thing is, I still need that password to be encrypted. Should I have some sort of encryption service at the server side that gives me the password to throw at the token endpoint? Why not have the service just log in for me then return the token. How should I proceed?
Thanks ^_^
This seems like a general authentication question. You can solve it like you would solve user authentication. Think of it this way:
When a user signs-in into your app, they provide their data on the client, and then it is validated on the server. In order for them to stay logged in, they get some sort of token, either via a Cookie session, JWT or whatever. Which is then saved on the client and sent on each request to the server in order to verify they are authenticated.
The above is how websites can show "registered users only" content. By validating a previously given token on each new request.
Now, applying this method to your REST Api. A user needs to request a token (which should not be your master password, but a uniquely generated one, in a per-user basis), and then save it locally for X amount of time. Every time the user makes a request to the API they send that token, which is validated.
This is also how normal APIs do it. You will need a token or some sort either way. If it's really sensitive information you're showing, the token should update every now and then (from minutes to days depending on how sensitive). You keep a record of valid tokens in your server. That way, if any token is "stolen", then it will only be valid for a small amount of time.

Is it a secure way to handle returning user in ember?

I am using ember to write a web ui for a site that requires user to log in. Suppose the browser has stored some cookie from last login of a user. Now the user visits the site again. So, is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit? If so, what are the common ways to implement this? (I can't find anything from Google.) Furthermore, how do I create the cookie upon login? Is it a common way to just put a user id, password hash, and expiration in the cookie?
Additionally, any references related to this subject are greatly appreciated.
Edit 1
In light of Vohuman's answer, I think I can make my question a little more specific. Basically, what I want to know is a common and secure implementation to keep a user logged in, even when they close and reopen the browser. Namely, the life time is beyond the session scope. Take linkedin for example. If you are logged in and exit the browser. Then next time you revisit linkedin, you are still logged in automatically. Right now, what I can picture is a solution like the following.
When you first log in to the site, the server will return a cookie which includes an authentication hash token. Then next time when you revisit the site, the server will receive the hash token and thus authenticate your session.
So, is above flow basically what people usually do to keep a user logged in? If so, is the JSON Web Token (JWT) basically one way to construct the hash token I mentioned above? Additionally, assuming the connection is HTTPS, this approach seems secure to me. Is it not?
Edit 2
This article gives an interesting discussion regarding where to store the access token.
is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit?
Yes and no. Security is a complex topic. Usually session cookies are used for authorizing users. This is actually the most used method of keeping the users logged in. If the user can't keep his credentials secure then any layers of security can be vulnerable.
For Single-page applications usually access tokens are used instead of cookies and sessions. The client sends the user credentials and server returns an access token. The token is encrypted and expirable and can be stored in localStorage or sessionStorage. Using JSON Web Tokens (JWT) standard is a popular method for implementing user authentication and authorization in web services. As an example, the Facebook Open Graph API uses access tokens.
JSON Web Token (JWT) is a compact, URL-safe means of representing
claims to be transferred between two parties. The claims in a JWT
are encoded as a JSON object that is used as the payload of a JSON
Web Signature (JWS) structure or as the plaintext of a JSON Web
Encryption (JWE) structure, enabling the claims to be digitally
signed or integrity protected with a Message Authentication Code
(MAC) and/or encrypted.
edit:
So, is above flow basically what people usually do to keep a user logged in?
For traditional websites, yes.
The whole point of using access tokens is keeping the web service/API stateless. This means that server doesn't have to store any cookies/sessions for authenticating and authorizing users. The stateless is one of the key factors of implementing web services that follow the REST paradigm. It's client that has to store the token and send it to the server (via the Authorization header or query parameters). The server doesn't store the token. Of course, you can store the tokens on the server if you want to add another layer of security, but it's not so common and not necessary. Storing the tokens on the server can also make your application vulnerable to database attacks and is not recommended.
If you want to make the process more secure you can decrease the validity time of access tokens (1 hour, 1 day or 1 week, it's up to you).
As for localStorage, is it secure?
localStorage data are stored separately for each origin (domain). A malicious user can only read the data if he/she has access to the user browser. You should make sure that your app doesn't have any XSS vulnerabilities so malicious users can't inject any scripts to your application. This is actually a different topic.

Most efficient way of authenticating and storing user login info in node.js

I know of two ways of storing and authenticating the user login info:
Storing the user id in a server side session and then when someone calls to the server check if they have a user session. (Using node client sessions)
When the user logins, store a authentication token in the user's table and store the token locally on the users client as well. Then when the user calls to the server they send the authentication token as a header and check if the token is in the user table.
While both of these ways are viable and applicable, I have problems/questions with both of them:
I've been told storing the info in session goes against the rest api idea of auto scalability. Is this true and is there a way around it?
When storing the authentication key, won't you only be able to store one key/instance per user. What would you do if you wanted to have the same account logged in on two computers or clients (I know I can just create an authentication table, but what if a client loses a token and the authentication token stays forever in the authentication table).
If there are better ways of doing this please bring it up, but I am very confused which direction to move towards. I am gravitating toward the second way, but I still like the first way.
Edit: I have narrowed it down to JWT and my second idea. I don't know which would be better with node.
How about JSON Web Tokens? They're a variant of the second method you mention and are a recognised industry standard, so you can easily find an implementation for your stack.
You can store the tokens in a key-value store like Redis instead of a relational database, which will be much faster. Redis also supports timing out a key after a while, so expired tokens will disappear automatically. You can also set it up so that each token is invalidated once used, and any request to the API returns a new token for use in the next request, allowing users to continually refresh their token.
Assuming you are using express, you can use express-session for managing your sessions.
Then, you need to add a suitable session store instead of the default MemoryStore, which is for debug use only, and will not scale to more than one process instance (for the reasons you mentioned in your question).
Fro example, if you are using a PostgreSQL database, you could consider using connect-pg-simple. This would store your sessions in your DB, so that your session management does not prevent you from scaling your node.js server. In addition, you can store multiple sessions per user, that will expire (and get automatically erased) based on the maxAge that you configure, thus solving the second problem you mentioned.

How to use JWT for a proxy server written using Node.js?

This is absolutely a newbie question & I am Node.js beginner.
I am not sure, this is right place to ask this question. But I may need idea from this large community. So let me explain what I am trying to do.
Server Configurations:
Node.js - 4.0.0
Hapi.js - 10.0.0
Redis
Scenario:
I am writing a proxy server in nodejs using hapijs. My Backend is ATG based e-commerce website and my api's are going to be consumed by web browser, mobile app etc..
We planned not to send the cookies sent by ATG to both browser and mobile.
So to maintain sessions and cookies from ATG,this is how we done POC.
First We planned without considering storing the anonymous user cookies returned from ATG. So we have done two POC's.
(Many of us know, what anonymous cookie is,any way let me explain that, if I put that one word -- Guest Checkout. There are many ways to accomplish this. But my Commerce Backend is implemented like this, When we go to website, you add items to cart and checkout that items without logging in right ? This what happens on background whenever we add the items they are only stored in your browser cookie,it not stored in persistent database, in any case user wants to login/signup to the account that cookie is retrieved from the browser and stored in database (basically that anonymous cart is transferred to logged in user.))
POC-1 (Not Considering Guest Checkout):
To access my api, user must be logged-in, after the successful login, We generate a rand-token and store it in Redis db associated with the cookies sent from the ATG for logged-in user and set ttl for 1 hour and return that token to the client
Now whenever they invoke any of api methods, they should send the token in the authorization header, I will check for token validity and expand the ttl once again for 1 hour and retrieve the cookies associated with that token, set that cookies in ATG request options and make a request.
3.On logout, I will clear the cookie and delete the token.
I have successfully implemented JWT fot this scenario, by generating a JWT token with user logged-in information in jwt payload. Used hapi-jwt-auth2.
POC-2 (With Maintaining Guest Cookies),
My API Will have endpoint /auth/generatesession, which in turn will return a 64 byte random token (we are using rand-token npm module for that) which will expire in 24 hours.
All the methods needs that access token passed back to me in authorization header and I will extend that token ttl to 24 hours.
Now they can invoke any api methods, like addtocart or something, even after adding items to cart , suddenly they want to login or something I can use their guest session cookie and transfer that cart to persistent database after successful login.
Questions:
Should I use JWT for the second scenario? If so,
How can I implement JWT for the Second Scenario? (Coz, don't know about who is the user?)
Does anyone think this is good idea for writing proxy server like this?
How can streamline session expiry of this token with ATG session Expiry?
Does anyone of using Node.js like this? How does it scale ?
If anyone care to give me an idea how to write this proxy server, it will be much helpful for me.
I Apologize, if this is too long question, just my way of explaining things.
Thanks in advance.
Sure, why not?
You don't necessarily need a user. A JWT stores arbitrary data, the username can be blank or anonymous. If a user logs it, and provides a token associated with a guest cart, then it can be assumed that that user is allowed to claim the contents of that cart, and the anonymous cart can be destroyed.
Sure, this is quite common (disclaimer: I've worked on something very much the same as you).
TTL is reasonable, but I have no idea what ATG is or how it handles it.
Yes. It scales very well as long as you ensure your servers are stateless, and that you manage all your state through something like Redis.
Too broad of a question, I would just use Express + Redis/Mongo/Postgres.

Protecting user sign-up API

I am currently writing an HTML5 web app with a Sails.js (node framework) backend. Right now, most of my APIs are secured against the user authentication system I'm using with PassportJS. Unauthorized users trying to use my APIs will get a 401 error.
However, there's one hole in the system, which is the sign up API itself. I obviously can't secure my sign up API with user authentication (because the user wouldn't have had an account to sign in with yet), therefore anyone could easily spam the API with many fake accounts. On my sign up page, I have a small verification question on the lines of "What is 2+2?" (it is generated randomly) and it is checked on the client and if the answer is correct, the client sends a request to my sign up API route with all the necessary parameters like name, birthday and username. How can I secure this API to ensure that people must go through my sign up page, and cannot simply bypass this security measure and call the API directly?
Just as a note, my APIs are not RESTFul.
There are multiple possible ways.
First of all, you may consider adding a rate-limit to IP addresses. This is NOT 100% effective, but will certainly slow down some spam attempts. For example, you can limit the number of accounts created by the same IP address to 5 every 5 minutes.
Secondly, if you want to use some sort of captcha, consider reCAPTCHA. Among the different captcha services, this is particularly effective against bots, as they especially use words that fail OCR recognition.
Eventually, to make sure that people actually visit your signup page before calling the API, you can use a "security token". This is the same technique that is used for example to protect against CSRF (Cross-Site Request Forgery) attacks.
When the server generates the signup page, it also passes to the client an hidden field (for example "token") that contains a uniquely-generated value. The client will submit this value along with the form back to the API server when it requests the creation of a user, and the server uses the token to validate the request.
There are basically two approaches to generate these tokens.
First method
The signup page creates a random string/number and stores it in the database to be used as token. When the user submits the form, the server searches for that token into the database: if it's present, then the submission is valid; otherwise it fails. The token is then removed from the database.
Additional security can be obtained by storing into the database, along with the token, an expiration date and the client's user-agent (unlike IP's, user-agents are unlikely to change during the same session).
Pros: each token can be used only once.
Cons: the app needs a database, and it will be queried 3 times just for the token insertion, validation and deletion (requiring time and adding load to the database). You also should to purge regularly expired tokens from the database.
Second method
The signup page creates a token by digitally signing a plain-text string containing all the validation information. For example, suppose that you want to create a token that expires on 1411660627 (UNIX timestamp) and it's associated with the user-agent "Mozilla/5.0 ...". The server also possesses a secret salt (for example "123456abcde") that needs to be unique for the application and kept secret.
The signup page generates the token in a way similar to:
Create a plain-text string to be signed, by concatenating all the information. For example, if the expiration is 1411660627 and the MD5-hashed user agent is 0f7aee3e0a65ff9440d2a0183b4b1f49, your base signature would be something similar to: 1411660627-0f7aee3e0a65ff9440d2a0183b4b1f49.
Append the secret salt to that string: 1411660627-0f7aee3e0a65ff9440d2a0183b4b1f49_ 123456abcde.
Hash that string, using any hashing algorithm (for example MD5). The result is your signature: 0742d84065cb9497c1ba4c1d33190a93.
Concatenate your signature to the plain-text string to obtain your security token: 1411660627-0f7aee3e0a65ff9440d2a0183b4b1f49-0742d84065cb9497c1ba4c1d33190a93. This is what the user received and has to submit back.
To verify the token, then, a similar operation is done. When the server receives the token 1411660627-0f7aee3e0a65ff9440d2a0183b4b1f49-0742d84065cb9497c1ba4c1d33190a93, it performs these steps:
Extract the expiration from the token and check if it's still valid. If 1411660627 is smaller than the current timestamp, then it's still valid.
Compute the hash of the user agent and check if it matches the one on the token: 0f7aee3e0a65ff9440d2a0183b4b1f49.
Re-generate the signature as before: expiration-useragent_secretsalt using the data from the security token received from the user. In our example: 1411660627-0f7aee3e0a65ff9440d2a0183b4b1f49_ 123456abcde.
Compute the hash of the string as before. If it matches the third parameter from the token (0742d84065cb9497c1ba4c1d33190a93), then the security token is valid.
Pros: this solution does not require a database, but it's equally safe (as long as the salt is kept secret into the server).
Cons: the same security token can be used more than once until it expires.
It sounds like you're not making full use of your math-problem countermeasure--you're using it as a client-side barrier, but as you observed, a bot could just skip the client side and call your API. To make it more effective, instead of generating the question randomly on the client, you would generate it on the server, save the answer in the session (req.session.mathProblemAnswer = 4) and then send the user's answer with the API call so that it can be checked against the answer in the session.
Using a token as #Qualcuno describes in his answer will be effective against bots spamming your API endpoint directly, but there are bots that are smart enough to load your signup page, scan for hidden fields and submit the form (including the token). It's still a good idea to use CSRF protection though in general, which Sails has built-in support for.

Categories

Resources