3

I'm trying to secure a REST API that I'm using as a backend for a single-page application. The API provides access to read/create/modify/delete protected resources, based on a set of permissions managed by an administrator. What I'm thinking is the following:

  • All connections must be over HTTPS; plain HTTP requests will be redirected to HTTPS.
  • Users have a username and password, which they create.
  • A client submits a username/password to a /login route; if it's a valid password for that user, the server will return a short-lived access token and a long-lived refresh token.
    • The access token will be a signed JWT that identifies the user and has an expiration time.
    • The refresh token will be a GUID corresponding to a row in a database table; this row will store the user ID
  • When accessing protected routes (everything but /login), an access token will be required. The server will verify the signature, and if valid, will check the expiration time. If the token is not expired, the user ID will be made available to server-side code for authorization logic.
  • If the access token is expired, the client will automatically submit the refresh token to a /refresh endpoint for requesting a new access token. The server will check the database; if a corresponding row still exists, a new access token will be returned to the client.

Does this scheme sound secure?

3
  • I apologize for not including anything about a threat model; I'm not sure what information to provide on that front.
    – DylanSp
    Oct 25, 2019 at 13:58
  • 2
    Since I misunderstood (and thought that the refresh token was the GUID for the user table), I went ahead and deleted my answer. As long as your refresh token is revokable (which it is), then you're pretty much implementing a standard JWT authentication flow, and it sounds very reasonable. The devil is in the details of course, but from what you've described here I personally think this sounds fine. Oct 25, 2019 at 14:31
  • @ConorMancone Thanks for the vote of confidence! "Pretty much...standard" is what I'm aiming for; I don't want to try creating something too novel.
    – DylanSp
    Oct 25, 2019 at 14:39

2 Answers 2

1

Okay! Caveat emptor, first off: I’m a rando on the internet, don’t make decisions off this, YMMV, etc.

With that out of the way this seems pretty much fine to me. Nothing seems out of the ordinary here. The main thing I’d check is securing the secondary endpoints, like /refresh. Make sure that one can’t be fiddled with, for instance. And make sure you test all of this thoroughly in your test suite.

2
  • Thanks! Anything particular to check/test w.r.t. the authentication-related endpoints?
    – DylanSp
    Oct 26, 2019 at 18:55
  • Yes definitely! Make sure you can only do the things you’re supposed to be able to do, basically. Check that you can’t delete resources, that you can’t bypass authentication, check for providing incorrect or weird values, etc. Oct 26, 2019 at 19:09
0

A general rule of thumb is "don't roll your own security".

Firstly answering the main question, whether the security scheme using passwords, short-lived access JWTs, and long-lived refresh tokens a good way or not, it is. Well, it depends on the implementation though. Having a long-lived refresh token may seem to be a good idea, but is not. To understand this better, let’s consider a scenario where an attacker gets hold of a refresh token. Now the attacker can keep accessing that user account till that particular refresh token is not invalidated in your database.

Going through ITEF RFC 6749 and ITEF RFC 6819, you’ll understand why refresh token should be used only once and why rotation of refresh token is required. Well, good news, you don’t really need to go through the whole doc. Here is an important quote from this documentation:

“The authorization server could employ refresh token rotation in which a new refresh token is issued with every access token refresh response. The previous refresh token is invalidated but retained by the authorization server. If a refresh token is compromised and subsequently used by both the attacker and the legitimate client, one of them will present an invalidated refresh token, which will inform the authorization server of the breach.”

Well, it’s tricky as well as complex to have a correct working solution where we can assure that refresh tokens are used at most once and are rotated correctly. The scenario where refresh token might get lost during the transit is not easy to handle either. We at SuperTokens have found a perfect solution that doesn't only do the rotate the refresh token on each use but also helps to identify the token theft scenario, i.e. if someone has stolen your refresh token.

Well, of course, the solution also takes care of preventing various session related attacks such as XSS, CSRF.

1
  • 1
    Please don't advertise
    – schroeder
    Apr 6, 2020 at 14:13

You must log in to answer this question.

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