Search code examples
securityoauth-2.0keycloaksession-storagepkce

OAuth2 PKCE Flow - Using Access tokens securely from Single Page Apps


I have an Angular application that uses angular-auth-oidc-client for integration with KeyCloak server

I use PKCE flow and I get the id token, access token and refresh token from the Keycloak server (OIDC provider). I do not need the refresh token, but Keycloak server seems to return it always even if scope does not use "offline_access".

By default the OAuth library stores all the tokens in session storage. I have written a custom storage to ignore refresh tokens and not store them in session storage.

I have read on internet that session storage are not completely secure storage, and a stored XSS attack can retrieve the tokens. However, mitigation for Stored XSS is to use standard frameworks like Angular which I am using.

Assuming a near impossible scenario of Stored XSS vulnerability, is the above solution secure wherein I use access tokens from session storage to call my backend APIs.


Solution

  • CURRENT BEST PRACTICE FOR SPAs

    There are more attack vectors and unknowns when using access tokens, and the current best practice is to use a Backend for Frontend so that only HTTP Only SameSite=strict cookies are used in the browser.

    It is also possible to issue cookies via a utility API, to avoid impacting your overall SPA archirecture. At Curity our SPA best practices have further info on this, though it is a tricky flow.

    There is also a link to a whitepaper that discusses threats in more depth. To some extent also, the solution you choose will depend on how high worth your data is. For medium and high security data solutions the cookie only solution is currently preferred.

    MULTIPLE SPAs AND SINGLE SIGN ON

    SSO is a property of the Identity Provider's session cookie, and also whether the app is using OpenID Connect parameters such as prompt=login and max_age. So multiple SPAs can still achieve SSO using BFF solutions, with each app being issued different tokens.

    Multiple SPAs must use isolated cookies when calling APIs, and therefore distinct API routes. This adds complexity, so I understand the concerns. I also liked the simplicity of the older Javascript only solutions such as oidc-client.

    ATTACK VECTORS

    These include things like capturing tokens in flight to APIs via monkey patching of the fetch API, an attacker spinning up a hidden iframe that gets tokens, or interception actions by browser extensions.

    If tokens are intercepted somehow they can potentially be sent out of the browser. A content security policy should reduce the risks of this, but users or plugins can disable them. This video discusses threats and is quite interesting.

    PERCEPTION

    This is one of the biggest factors - if you ever have to explain your security to customers, stakeholders or PEN testers. If you are following the BCP these conversations are easier. Otherwise, in some sectors, you may face difficult questions.