1

Somehow implementing stateless authentication always brings me headaches.

This time it concerns silent auth vs refresh tokens.
Using refresh tokens seems discouraged, however there are certain arguments I don't really get.

If you use an http only cookie to store your refresh token, what exactly is the danger?
Attackers cannot get access the cookie with Javascript and if you use SSL (which you should), I really don't understand the problem.
The resources I read always say "you should not store sensitive data in the client". Seems like an automatic, but that is implicitly impossible if you want to eliminate the need for server session state. Neither do I really understand why, since no resource ever explains how it would be cracked (and I really wonder if anybody really knows).

The reason why I have this question is because using a refresh token offers me more than just authentication.
If a user for example loses his / her device, removing the refresh token will just invalidate all access tokens over all devices (not only browser), which seems like something a user wants to do.
After all, it makes sense that when you lose a device, you need to take action to protect your data.

So the argument "if the attacker gets access to the refresh token, he can infinitely refresh your token" sounds like another argument I don't get. The attacker should not get the refresh token. How would he ever get it? It's the same as saying "if the attacker gets hold of the code of your bank card, he has infinite access to you money". Well if you lose your bank card, you call card stop; likewise if you lose your refresh token, you would delete it to invalidate all access tokens. So how is this an argument?

Can you clarify why I cannot just store my refresh token in an http-only cookie, and how a silent authentication flow improves on this?

Edit: Note that I read a few other articles that advise to store jwt in the browser by sending the encrypted jwt signature in an http-only cookie. These articles received a lot of upvotes, so that is suddenly okay. It makes zero sense to me.

Edit on comment:

The architecture is very simple:

  • React / Redux SPA with REST api in the backend
  • Need for social login through Google, LinkedIn, Github
  • Need to refresh the token without needed user interaction
  • Access my own api resources (preferably with jwt)
  • Ability to revoke refresh token

I don't know why it seems complex (lol).

html_programmer
  • 18,126
  • 18
  • 85
  • 158
  • Trace, it would be good to describe your architecture (browser app, backend) and reasons why you want to use OAuth2 tokens. There may be specific solutions for different scenarios. It's hard to reason about all the possible variations. – Ján Halaša Dec 18 '19 at 20:47
  • @JánHalaša Added this now – html_programmer Dec 18 '19 at 20:49

1 Answers1

0

Refresh tokens are widely used in:

  • Server side web apps, where they are stored in an HTTP only cookie, as you suggest
  • Desktop and mobile apps, where they can also be stored in OS secure storage

Refresh tokens should not be infinitely renewable and often represent the user session time - eg:

  • Refresh token / User session lifetime = 12 hours
  • Access token / API message credential lifetime = 60 mins

The concern for SPAs in the above article is that there is no real secure storage in the browser - though you are not intending to use browser storage - so no problems there.

One risk is that users can maybe get the secure cookie and replay it to an API via browser developer tools:

  • To mitigate this it is of course important to ensure that APIs have well engineered authorization - and that what the user can do with a token matches what they can do in the UI.

  • Another risk is CSRF where a malicious app in another browser tab sends the same cookie to your back end. So you'll need to protect against this.

Note that SPAs have their own token renewal solution based on Authorization Server cookies - I would prefer that option if using an SPA, rather than issuing your own cookie.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
  • Hi @Gary. Thanks for the answer but I have a few issues with it, I'll enumerate them. 1) You mention SSR webapps, but is it a fact that an SPA cannot have a http-only cookie through REST (it doesn't look that way)? 2) Get the cookie through browser developer tools doesn't make much sense to me, the http-only cookie can not be accessed from Javascript (this is its purpose). 3) Why mitigate a risk that isn't there? CSRF protection ok, I can handle this. I'm looking for a reason not to follow this flow, i.e. store jwt + oAuth refresh token in an http only cookie. It seems a viable approach. – html_programmer Dec 18 '19 at 20:44
  • The article you link uses session authentication, which I want to avoid. Everything seems te revolve the question whether the http only cookie is secure. Any article I read dances it way around it, but the core explanation mentions explicitly, anywhere, that it cannot be captured from Javascript. So if it were one day to be released in developer tools, this would be the blunder of the century, and a lot of systems would be broken out there. – html_programmer Dec 18 '19 at 20:45
  • 1
    Oke, the session in the article may not be what I thought it was although I found it a bit confusing. For example: `The OIDC Client library works by periodically checking the time until the UI’s access token expires, then triggering a renewal when it is close to expiry`. Say you lose a device, the system will keep on refreshing your access token. How is an automatic refresh more safe? With `prompt=none` it's like you say, just refresh it please. You cannot revoke it (?). Using an iFrame to work your entire way around the http-only cookie, is that really necessary / useful? – html_programmer Dec 18 '19 at 21:05
  • Interesting chat Trace. Usually only old style web apps use cookies (I wasn't referring to Server Side Rendering). Browsers prevent JS code from reading http only cookies, but ultimately they are just headers and browser tools + HTTP proxy tools like Fiddler enable them to be viewed or copied - see the Session Expiry section of the token renewal link above. The most secure option for an SPA is to follow the standards:: https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-04. – Gary Archer Dec 18 '19 at 21:17
  • In an SPA the Authorization Server issues a session cookie. This has a fixed expiry - very similar conceptually to a refresh token. So if you lose a device the token is only usable for a fixed period such as 12 hours. – Gary Archer Dec 18 '19 at 21:20
  • I will go through it, thanks for your explanation. Just from personal interest: I don't quite understand why they go through the hassle of finding workarounds, while it seems so much easier to just encrypt headers with a secret. The only purpose this header should have is authentication. It should be transported, stored at a client and sent back. I'm spending more time on authentication than the entire rest of my app currently. All of this seems very bloated to me, but that is perhaps just my humble opinion, or either I'm missing something else. I also strongly doubt the majority does this... – html_programmer Dec 18 '19 at 21:22
  • And missed the part where you said 'copied', sorry for that, it is a valid argument. – html_programmer Dec 18 '19 at 21:26
  • The state of the industry is not perfect - so I understand your concerns - typically the best option is to plug in the [oidc client library](https://github.com/IdentityModel/oidc-client-js) to manage the complexity for you. My blog has some code samples on how to do this. – Gary Archer Dec 18 '19 at 21:28
  • 1
    I know that feeling! I've been working with payments tech recently and the encryption is killing me!!! – Gary Archer Dec 18 '19 at 21:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204507/discussion-between-trace-and-gary-archer). – html_programmer Dec 18 '19 at 21:29