Where should a SPA keep a OAuth 2.0 access token?
Asked Answered
E

2

20

In a Authorization Code Grant flow, once a public client such as a Single Page Application (SPA) obtains a OAuth 2.0 access token, where should the SPA keep it?

  • Storing the access token in locale storage or session storage opens up to cross-site scripting (XSS) attacks, so that should be avoided.
  • Storing the access token in a non-httpOnly cookie also opens up to XSS attacks, so that should be avoided as well.
  • Storing the access token in a httpOnly cookie is not technically possible because that is the point of httpOnly.

So the only secure remaining option that I see is to keep it in memory. Is it actually secure? Is it the only secure way?

Exotic answered 24/5, 2019 at 16:6 Comment(0)
O
18

It's all about the risk you want to accept.

If you store it in a cookie, you potentially open up your application to CSRF. While it may make sense to exchange XSS for CSRF by storing the token in a httponly cookie, it doesn't make much sense to do so with a non-httponly cookie that besides CSRF is also vulnerable to XSS.

Storing it in localStorage or sessionStorage is ok in many cases. With choosing that, you accept the risk of XSS having access to tokens. To mitigate this risk, you might want to implement mitigations, like for example static security scanning with a suitable tool, regular pentesting and so on - security is not just code, it's also processes around how you create that code. With mitigations in place, you can decide to accept the residual risk.

You can also store tokens in memory, like for example in IIFEs I guess, from where it's somewhat harder to read in an XSS attack. Storing it in a plain variable doesn't help (javascript from XSS would still have access), and I'm not entirely sure about what the latest JS can do to securely make it inaccessible from outside a given object. It's probably not possible in a way that is actually secure.

Or you can go down a different route. You can store very short-lived access tokens in localStorage, accepting the risk of XSS having access. However, your IdP can issue refresh tokens in httponly cookies for the IdP domain. This way even if an access token is compromised, it is only valid for a limited amount of time, and then the attacker will not be able to renew it. This may make sense in some applications, and probably not in others.

Ornithomancy answered 24/5, 2019 at 17:35 Comment(0)
W
0

As always: It depends.

  • Old skool Auth Code = Store token on server side
  • Auth Code + PKCE Public Client = Store at client side

Auth Code as described in RFC6749 (old skool)

Don't use this client side, use Auth Code + PKCE instead.

The Authorization Grant flow as described in RFC6749 (https://datatracker.ietf.org/doc/html/rfc6749). In this "flow", the client sends a request for a code to the authorization server, the server responds with a code, the client exchanges the code for a token. (Don't use this on the client side, use server side only)

Lately, this is the preferred solution for web apps. The trend is to create a confidential client and have the code <> token exchange take place on the server side. (https://datatracker.ietf.org/doc/html/rfc6749#section-2.3). That way, only the computers that have been entrusted the client_secret are able to obtain a token.

Auth Code requires storing the access token on the server side.

(Note: this flow is also used for mobile apps, but that's a topic on it's own...)

Auth Code + PKCE (Public Client) as described in RFC7636

The second type of "flow" is the Authorization Code with PKCE (Public Client) as described in RFC 7636 (https://datatracker.ietf.org/doc/html/rfc7636). This flow is designed to use on the client side. In this scenario, the client generates a password (a.k.a. code verifier) and includes that in the request for a code to the authorization server. The server responds with a code, the client exchanges the code+the password for a token.

In case of "flow #2", the public client, there's one important risk to consider. In case of Code + PKCE Public Client, there are no constraint to which computer may initiate the authentication request or receive the token. That means that if an attacker could have means to obtain the code verifier and the code, and if the attacker succeeds, the attacker is able to exchange it for a token. If this is an acceptable risk to you, or if this risk is mitigated, feel free to store the token in the SPA with the considerations that Gabor mentioned

Hope this helps?

Wriggly answered 15/5 at 7:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.