Logout in token-based authentication and Single page application - java

I'm using JWT authentication for my Spring Boot application. The front-end is going to be a single-page-application.
Should I handle logout functionality on the server side? As far as I understand, there's no way to invalidate a JWT token unless we have a stateful server (storing logged out tokens for the maximum lifetime of a token).
The SPA passes the JWT token every time making a request in its header, and it can delete it from the localStorage when the user visits /logout without making a call to the server.
What are the potential issues? Is this idea used anywhere else? What is the best practice?

First of all you must decide wether you want a statefull server, or not.
statefull server
this is easy. Just send a logout request to the server and throw the session away. That's it. That's the safest way.
stateless server
I like stateless servers because you don't have to manage the state. But of course you have a tradeoff. In this case the securety. There is no way to logout because you don't have a session that you can invalidate on the server side.
So an attacker which steels your JWT-token can use the session until it ends and there's nothing to do to prevent this.
But you can do something to avoid that the atacker can get the JWT Token. Here are some things that you can do and that you have done already right
Don't use cookies to send the token. The way you do it is perfect. Use the header. This is encryptet by SSL and Single-page-app must send it on purpose.
Put a timestamp into the JWT-Token so that it invalidates itselve after some time. But be aware of effects like Timezones and Clocks wich are out of sync.
Put some browser fingerprinting information into the Token like the OS or the Browser version. In that way the atacker has also to fake that.
But these mechanisms are all there to make it harder for an atacker. A real logout is not possible.
Note
If you use JWT correctly your server will have a "state". You have to define a secret that is the same on all servers. That's something you must be aware of, if you use multiple servers.

Related

What is the most scalable/secure way to handle refresh tokens in a JWT authentication setup?

I am building my own authentication microservice and although I have the main setup in place (generating access tokens etc.), I am a bit lost when it comes to refresh tokens.
I feel there are a lot of different way to handle this.
You can either store them in Redis or in the database.
You can use a whitelist or a blacklist them
Right now, my idea is to add another database table that links a valid refresh token to a user entity. When a user hits the logout endpoint, the refresh token gets destroyed.
I was wondering if this was a good solution and otherwise, if there are other possible solutions to consider. I have seen a number of articles when googling but they stem from anywhere between 2015 and 2019, and they all have different approaches.
The issue with refresh tokens is not so much where or how you store them on the server side, as well if and how you store them on the client side.
It all depends on whether you can trust your client (software using the token) to keep secrets. You only want to issue refresh tokens to a client you can trust to keep these tokens secure. Typically, this means only issue refresh tokens to confidential clients, i.e. web applications that run on a web server. These clients can also have their own (client) credentials to authenticate themselves with when using the refresh token.
For public (non-confidential) clients, like Single Page Applications, some OAuth2 libraries use an hidden IFRAME and a cookie session with the authorization server to issue new access tokens.
So, the answer to your question depends on what kind of clients you will be using.

RESTful token and session

I would like to know what is the best practice on how to work with authorized RESTful server.
Say that after login the server provides me a token, and then for each request I will have to provide it as well. My question is: should I save this token in my server's session? or should I do authentication against the data base for each request?
There are several ways. You could only keep it in memory, but then if you have multiple servers in a cluster, you'll have to make sure a request for a given token always goes to the same server, or to distribute the token among all the servers.
You could also cryptographically sign the token data, include the data and the signature in the token, and verify the signature at each request. That way you can be certain that the token has been issued by you, and you can be completely stateless.
Note that, if you're using HTTP sessions already, the token is redundant, since the session mechanism already uses a token in a cookie to track sessions.
Use a session cookie to track an authenticated session instead of hitting the database each time.

Securely storing credentials for repeat web service calls

I'm working on a web application for internal use that is driven by many web service requests to another remote server. The internal site maintains its own session, authenticated by username/password credentials that are themselves backed by the web service(i.e. we make a remote authentication call to verify the login to the internal site). The web service requests also require authentication using these same credentials.
We were hoping these web service requests could remain stateless, which means passing the credentials in with every request for authentication. The problem is remembering the credentials to be used(the ones entered during the initial login) in a way that is secure. I'm not aware of any truly safe way to store a password for later re-use - hashing it would sacrifice our ability to use it again. The best we could do would be to encode it in the session scope and hope that no malicious developer will ever try to catch it in a thread dump or something.
Is there a better solution to this that I'm missing? Am I being overly paranoid about the risk of storing an encoded password in memory, or is our approach to this project flawed?
i would suggest to use token based authetication, a token is passed to the user for cheap user verification on the fly. One implementation of this would be to generate a cookie that is passed to the user for session management.
i have not used but you should look at oauth may be example
Ultimately our conclusion was that no, storing user credentials on the server that are re-usable in any way is not safe, so we can't do truly stateless re-authentication on each web service request. We simply had to compromise and preserve a stateful connection that is initiated and stored during the user's initial login.

Securing every request of a session by challenge/response?

We need to design a secure web application. I would like to propose a session handling mechanism which does a challenge-response on every request, not only during login using a CRAM method.
The reason is to harden the web application against session hijacking (eg by CSRF) and replay or man-in-the-middle attacks.
Using a nonce is suggested in some places, but in our webapp it seems impractical, as asynchronous requests can go on, or the user could open new windows, hit the back button etc.
Idea: The client and the server have a shared secret (a previously established user password), every subsequent request does again a challenge/response based on that secret, e.g 'response = hash(challenge + hashedPassword)'. The server executes the request only if the response to the challenge matches. Much like during CRAM, but ongoing for every request.
The question: Is this a feasible idea? If so, it surely has been implemented or is even some standard? How would we use this in a java or php based webapp?
The question really comes down to what you want to achieve. If you want to fight CSRF-Attacks, a secret token in addition to the session key is your way to go. However, changing the token in every request will cause problems - not only will the back-button kill the session, but as one webpage usually contains a lot of asynchronously and parallel loaded data (images, css, javascript, etc.), your approach will not enable any additional data to be loaded afterwards, as each additional request will change the required token, thus killing the session.
You may get around this by embedding all resources into the page via BASE64 and other tricks, but that will seriously hinder your possibilities and may have compatibility issues with some browsers.
So, in the end, your approach will not add much security, but will most likely create a whole set of potential problems for your customers. I'd stick to one secret token per session in the URL to fight CSRF and concentrate on securing against other attacks like XSS and user-friendly security measures like two-factor authentication with a smartphone or something similar. After all, the user is the #1 attack vector nowadays.
Update (2012-06-14)
The token will not fight XSS-attacks, but it will defend against basic CSRF-attacks (e.g. by implanting a bogus url call in an image). I've actually had a situation at work today, where I needed to secure a get-request against user modification and worked up some code. The code may be also usable to secure static, session-timeout form- and link-tokens (right your problem).
The idea is to have a server-secret, which is used to generate a hash/AuthToken over data to secure. If a rogue javascript would try to change any of the given data, the AuthToken would not match. In my specific problem, I have one server authenticating a user and have to send his information over to a third party (username, mailaddress, name, etc.). This GET-Request might be easily changed by any user after authentication, so I have to authenticate the GET-Request-Parameters. By rerunning the AuthenticationToken-Process, the third party can compare the resulting AuthTokens, thus validating the incoming data. Without the shared secret, it is (near-to) impossible to forge the data.
On your problem: Having a static token on GET and POST-requests (or a dynamic one like the project of mine) will protect you against simple CSRF-attacks via e.g. links in forums, which a user has to click to get attacked. As the link will never contain the correct token, your webpage is secure. However, if an attacker manages to load a javascript into the webpage via XSS, you're screwed and no technique in the world will help against it, as the javascript can scan the whole DOM-tree of the page to find an capture any tokens whatsoever.
So, it comes down to this:
use tokens on GET and POST-requests to fight CSRF
secure your page against XSS-injections
I find the OWASP cheat sheets are a good resource for such design decisions:
CSRF Prevention Cheat Sheet
XSS Prevention Cheat Sheet
Your scheme sounds similar to the HTTP digest authentication without establishing any kind of session post authentication. Which is probably an improvement over HTTP Basic. And that is assuming both are over TLS!
I am not sure how feasible your scheme might be or how vulnerable to replay attacks or MITM it might be.
If it is an option you might consider the new <keygen> html5 tag which can help establish a two way TLS session. This would be the most secure option..

Spring doesn't set an AUTH cookie by default, after logging in. Why?

I am working with Flex and Spring on a project, where I need to authenticate my users to give them the chance to build their personal profiles.
On my services side I made two very simple methods login and logout, which the Flex client calls through a remote object. What I noticed, though, is that apart from the JSESSIONID cookie, Spring doesn't set any other authentication specific cookie. Thus, when I try to do something auth specific, for example logging out, or requesting data from a specific service, the server breaks my client state, because the session might have expired. However, the client doesn't know anything about that.
In fact, I don't want sessions to expire at least until I close the browser completely. The normal JSESSION expiry time is 30 mins, I think, which, if we speak about the server is completely understandable, since the server must have a reasonably timely management of the sessions (resp. threads) being open.
That's why I need a second AUTH cookie, which by default expires on browser close. However, I am also thinking f implementing something like "Remember me" which should increase the expiry date with 14 days.
BTW, I assumed that Spring Security takes care of this automatically, by setting an AUTH cookie by default, but this is not the case. I think that it at least the authentication instance with the current session, since, after I log in, all the security rules I have take place absolutely fine .... until the Jsession expires, of course.
NOTE: Whatever you propose, please have in mind that there is also an AJAX client under development, which will more or less use the same infrastructure, so the cookie solution has to apply to both.
Thanks.
See http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html.

Categories