Why are Refresh Tokens considered insecure for an SPA?

孤者浪人 提交于 2019-12-03 14:09:36

Good question - So there is no really secure way to store any tokens on a Browser (or any other confidential info) - see links such as this. Hence Single Page Apps (SPA) should not store a refresh token - a refresh token is particularly problematic, because it is long lived (long expiration or no expiration), and if stolen then an attacker can continue to refresh access tokens after each individually expires.

It would be better to just retrieve your access token when you need it (for instance to call an API) and either store only in memory (still vulnerable to XSS / CSRF) but better - or use and forget. Then make another checkSession call next time you need an access token.

To your question - the checkSession request does not require sending a Token. It is literally as the name suggests - a "check session" against the Authorization Server to see if a Session exists. If it does, then the Authorization Server response will include a fresh access token. See here for an example usage with SPA

Please feel free to leave me comments beneath this answer if anything requires more clarification etc.

The refresh tokens are not used in SPAs, because in order to use it - and to get a new access token from the /token, the SPA needs to have a client secret, which cannot be stored securely in a browser. But since the OAuth 2.0 for Native Apps RFC recommends not requiring a client secret for the /token endpoint (for public clients), the refresh tokens could be used even in SPAs.

To get a refresh token, you need to use the Auth code grant, which passes the code in a redirect URL, which goes to the server hosting the SPA (which can be an extra point of attack). The Implicit grant delivers tokens just to a browser (hash part of the redirect URL doesn't get to the server).

The difference between using a refresh token and an SSO session cookie - the cookie is probably more secure, since it can be marked as HttpOnly, making it inaccessible for attacks using JavaScript code.

There are a lot of misunderstandings about both cookies and refresh tokens and OAuth2.

First, it is not true that only confidential clients can use a refresh token. The OAuth2 protocol says that confidential clients must authenticate, but does not require confidential clients. Ergo, client authentication is optional on the refresh operation. See RFC 6749, Section 6, Refreshing An Access Token.

Second, you have to understand what the alternatives are:

  1. Forcing the user to enter his or her username and password every 5 minutes (whenever the access token expires)
  2. Long lived access tokens
  3. Authentication via HTTP Cookies

Everybody in the world, who doesn't use refresh tokens, uses option #3. Authentication via cookies is functionally and security-wise 100% equivalent to storing a refresh token. Of course, with both tokens and cookies, there are options for where they are kept:

a. HTTP only, b. secure (require TLS/SSL) and c. session (in memory) vs. persistent (local, domain storage)

The "HTTP only" option applies only to cookies and, thus, may represent the only advantage of using cookies over tokens. I.e. tokens are handled via Javascript, so there's no option to keep them away from scripts. That said, the tokens are available only to Javascript from the domain of the page that stored it (or as allowed by CORS policy). So this issue can be overblown.

Of course, care must be taken to always use TLS/SSL to transmit either authentication cookies or tokens. Honestly, since we know most breaches occur from within the private corporate network, end-to-end TLS is a basic requirement anymore.

Finally, whether cookies or tokens are ever persisted, i.e. stored somewhere that survives closing the browser or even rebooting the device, depends on the trade-off you're making between usability and security - for your application.

For applications that require a higher level of security, just keep everything in memory (i.e. session cookies, tokens in a Javascript variable). But for apps that don't require as much security and really want a session life on order of days or weeks, then you need to store them. Either way, that storage is accessible only to pages and scripts from the original domain and, thus, cookies and tokens are functionally equivalent.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!