2

Currently I am developing an iOS/Android app and a corresponding backend in PHP. In the last days I read a lot about user authentication and now I am a bit confused.

For now I am using a session ID for user authentication. A user can login in the app using email and password. The credentials will be send to the server in a post request and then I will generate a session ID in PHP. The session ID is returned to the app and after that used for calling the API.

The session ID is currently only expiring if the user is logging out or if he changes his password.

I am now wondering if my solution is secure. I read a lot about OAuth but it seems to be hard to implement and I do not really understand the security benefit in my case (except that the keys are expiring).

So my question: Is my solution secure or should I somehow improve it? How secure is it compared to OAuth?

0

1 Answer 1

5

Oauth is an authorization system, not an authentication system.

OAuth is intended to provide secure access to a resource by a third party. For example, there are applications that allow you to schedule posts to various social media platforms, such as Facebook and Twitter. These applications will store your posts then, at the scheduled time, make a post to that system on your behalf, without having your credentials.

Another common use is, if you are a third party, such as an information scraping tool that is set up to look like a "What color pocket lint matches your auras" poll, such apps will be given some identifying information about you, such as your name and user ID (and possibly a LOT more, if you don't check the permissions carefully.) These provide a round-about identification system, that can sometimes stand in place of authorization, if you trust the OAuth provider. That is, there is no way to prevent this OAuth provider from lying to you about the identification; an admin for the provider could claim to be one of your users and you would have no way to know for certain, if you use their OAuth service as authentication.

If you want to identify users of your mobile app, you could have a "Sign in with [social media platform]" option using OAuth. This can decrease some of the friction of signing in, compared to using a username and password. Just keep in mind that, in this case, you're not the one authenticating your users.

As far as authenticating a user with a normal username and password in your app, and having a session ID passed with each request; this is how most sites work. The OWASP cheat sheet on session management goes into details, but the general best practice can be summed up as:

  • At least 128 bits (16 bytes, 22 printable Base64 characters) long.
  • Generated with a cryptographically secure PRNG.
  • Does not represent anything except the session ID (don't include the username).
  • Before authenticating, switch to TLS. Never use an authenticated session in non-TLS.
  • Cookies may not apply to you, unless you're using a browser, but if they do apply, must have the Secure, SameSite, and HttpOnly attributes with properly configured (and not too permissive) domain and path attributes.
  • Recycled on privilege level change (login, logout, changing password).
  • Idle timeouts and maximum timeouts.

Since you are writing a mobile app, you have some more assurances that many web developers don't have. You do not have to rely on cookies for storing your session IDs, so you can get away with having two tokens; a short term session token for your API access, perhaps valid for a few hours, and the other (a "refresh token") to request your short term tokens. This refresh token should be much higher entropy than a session token. In any case, 256 bit tokens will protect against brute force attempts until the heat death of the universe.

You can also use this refresh token as a shared secret, rather than a simple ID like the session ID is. When negotiating a new session ID, you would send some random bytes to the client. They will append these bytes to their refresh token, and calculate a hash based on that, and send the result back. You then compare what they sent back with what your server expects (after doing the same hashing of the refresh token and your nonce). This proves that the client has the correct refresh token, without sending the refresh token over the network.

With this system, an attacker who performed a successful Man-in-the-Middle attack can only hijack a session for as long as you haven't recycled your session IDs, and users will not need to re-authenticate constantly, for as long as the refresh tokens are valid.

1
  • 1
    This is an excellent answer! Upvoted! Another strategy is to have change refresh tokens on each use - this not only improves security in the event of refresh token theft, but also helps detect it. This article explains this rather well. Nov 14, 2019 at 9:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .