11

I've been reading all I could about this subject for the last couple of days and I can't decide what would be the best approach.

The only two requirement are:

  • I need to know the users that are logged in and every session they have, so the user would be able to see a list with this information and be able to close any session they choose.

  • Both apps should use the same endpoints of a rest API.

At first I was using session cookies, and calling the API with setCredentials=true, but I found that mobile apps handle cookies differently and I don't have control over that (for example, they get deleted for various reasons before expiring). I thought about saving the cookie in native storage and appending it to every request, but I can't access the cookie in any way because httpOnly is set to true. The solution would be to set httpOnly to false, but this way I'm exposing the cookie and I'm not sure of what security measures I should put in place to protect the cookie from been stolen or tampered with.

The other solution would be to use JWT and store that in web/native storage. I would also store in a table every token still valid (hashed with a password algorithm) to get the list of users logged in and their sessions, and another table for invalid tokens for when the user chooses to end a particular session / changes password / etc. But again I'm not sure about the security measures I should us with this approach. Should I encrypt the token also? I was thinking about appending to it data about the device that ask for the token to always check that the device that asked for the token is the one using it. What other things I should do to protect this token?

If I implement correctly either of this options, which one would be more secure for both web and mobile?

Leia
  • 213
  • 2
  • 7
  • of interest: [cryto.net: Stop using JWT for sessions, part 2: Why your solution doesn't work](http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/) – Jacco Aug 08 '19 at 11:19

2 Answers2

6

Before going into the details I will say that both session cookies and JWTs work for your case and both are secure if implemented correctly. Personally I would go with JWTs if only because it's easier to get up-to-date information or ready-built solutions.

JWT

JWTs were really designed for stateless authorization in mind but you can still use them for sessions. You'll want to look in particularly at using an access/refresh token model where you keep track of active refresh tokens in your database.

As for encryption, there are two main implementation of the JWT standard, namely JWS (a signed token) and JWE (signed then encrypted token). What you want to keep in mind is that a signed token's signature already ensures the integrity of the token. You would only implement JWE if you are also passing sensitive information in the token that you want obscured from the client. However JWT by itself does not solve problems with man-in-the-middle attacks so you should remember to use SSL whenever transmitting the token.

Storage of the token will differ between your web app and mobile native app. For mobile apps you should store them in the OS's Keychain/Keystore (most likely through a wrapper) which is designed for such a purpose. Where to store JWTs on a browser on the other hand is still a rather controversial topic as storing in webstorage (sessionStorage/localStorage) is vulnerable to XSS-Attacks while storing inside a cookie is vulnerable to CSRF.

From what I can gather the general trend is to avoid webstorage due its larger attack surface, but to be honest I've seen examples of both methods. For single page applications you can also consider keeping the token in memory without persistent storage.

Session Cookies

Without knowing details of your mobile app it is hard to say but from my experience if you are using the CookieManager/NSHTTPCookieStorage mechanisms provided by Google/iOS there shouldn't be a problem of deleted cookies that you describe.

Storing cookies on the browser will require you to secure it against CSRF. For what protection you should use it will depend greatly on your specific server implementation and restrictions and I think you should check out the resources on OWASP or ask a more specific question.

AlphaD
  • 873
  • 6
  • 11
  • 3
    The problem with JWT: There is no session-management. So logout for example is not possible. Without a table of currently valid tokens you can't know where a user is logged in. If you have such a table you are basically back to session-management. So maybe stay with session cookies and addtionally use jwt for "credential replacement/remembering". – BenjaminH Dec 11 '18 at 10:37
  • Can't the logout feature on a mobile app (or website) just simply remove the JWT token? Hence on the next login call, its missing and the client can goto the login page since its been 'invalidated'... The downside I guess is you won't know if the user is currently logged in or not since no server-side tables. I saw a Mobile App I believe implemented like this at our work (not sure if its the 'right thing to do' security-wise). – armyofda12mnkeys May 09 '19 at 17:12
  • @armyofda12mnkeys Yea I think that's what Benjamin is referring to, that to keep track of current users with just the access token is not enough. Solutions I know are in use require either the db keeping track of refresh tokens or a mix of session cookies with JWT access tokens. – AlphaD May 10 '19 at 10:32
  • @AlphaD This in-house app I believe doesn't do either. It just removes the JWT token client side, there is no server-side db or session cookie to delete. It just checks on login if the user/pass is valid (via the db), and if so the token is issued to the client and the server never saves any information in it. On login, if the JWT token is valid then it allows the mobile app user into the app. On logout, it removes the token on the user's device. Was wondering if this is insecure though :). If so, I'll have to let the mobile app devs :). – armyofda12mnkeys May 14 '19 at 13:20
  • @armyofda12mnkeys I wouldn't worry if the app doesn't intend to keep track of session state. It just happens that the OP wants to do so in this case. – AlphaD May 15 '19 at 03:00
  • For iOS I have always used the cookie manager as Alpha is mentioning. No issues so far. A login automatically come back with the required cookies and the app handles them. When user clicks logout you delete the cookies associated with domain that you are interacting with. Or all the cookies for the app if you want. As for Android, I am yet to try anything out. – pnizzle Feb 03 '21 at 04:01
-1

Do you trust all of your client code? If yes, you can store session IDs in local storage, and make sure to submit them with every HTTP request. On your backend, simply have a table with Session ID hash as the primary key, and User ID as the foreign key, and an expiry time. Don't keep a list of deleted sessions, just delete the row (or mark it as deleted).

The risk with cookies is that they're sent with every HTTP request to your domain, even if it originated from a fake client. This is called CSRF. Unless you have some sort of CSRF protection, avoid cookies and use local storage.

Of course, if you can't trust all your client code, then you'll need another solution.

Also, if you're using HTTPS, then session IDs, either cookies or form submissions, will be encrypted.

Irfan434
  • 719
  • 5
  • 7
  • It's considered "for both web and mobile app". So trusting the client code should not be applicable here. – BenjaminH Dec 11 '18 at 10:39
  • cookies can be flagged to be send over https only, there cross-site behaviour can be controlled with the sameSite flag. – Jacco Aug 08 '19 at 11:43