SPA (Angular, Vue, React) security issue, switch to PKCE code flow

These past few weeks I have worked on the implementation of OpenID within a Hybrid AngularJs / Angular application. For this implementation, I used the Angular OpenID client from Manfred Steyer. This client is OpenID certified and makes it easy to connect your Identity Provider (IdP). It supports implicit flow and PKCE code flow. There is also good documentation and examples so I am not gonna show you the code because it’s pretty clear in the documentation.
But what I do want to tell, is that by using implicit flow you are vulnerable to a couple of security issues.

Security issues implicit flow
Many SPA applications, that are build with Angular, Vue, React, are build using the implicit flow. But recent studies show that there are a couple of security risks you have to be aware of when you use implicit flow. Christian Lüdemann wrote a great blog about Angular and implicit flow and code flow with PKCE and the risks of using implicit flow. Check it out here!

So this means its time to switch from implicit flow to PKCE code flow.

sequence diagram of PKCE code flow
PKCE code flow

Identityserver4
As an IdP I like to use IdentityServer4. Many of you already know it and when I used implicit flow in my Angular app, my client configuration looked at little like this.

new Client
         {
            ClientId = "js_oidc",
            ClientName = "JavaScript OIDC Client",
            ClientUri = "http://identityserver.io",
 
            AllowedGrantTypes = GrantTypes.Implicit,
            RequireClientSecret = false,
            AllowAccessTokensViaBrowser = true,
 
            RedirectUris = {"http://localhost:4200/" },
            PostLogoutRedirectUris = { "http://localhost:4200/" },
            AllowedCorsOrigins = { "http://localhost:4200" },
 
            AllowedScopes =
               {
                 IdentityServerConstants.StandardScopes.OpenId,
                 IdentityServerConstants.StandardScopes.Profile,
                 "api1"
                }
          }

Identityserver4 PKCE code flow
In order to get the code flow working. Change the configuration in Identityserver like this.

      new Client
        {
           ClientId = "js_oidc",
           ClientName = "JavaScript OIDC Client",
           ClientUri = "http://identityserver.io",
 
           AllowedGrantTypes = GrantTypes.Code,
           RequirePkce = true,
           RequireClientSecret = false,
 
           AccessTokenType = AccessTokenType.Jwt,
           AccessTokenLifetime = 330,
           IdentityTokenLifetime = 30,
 
           RedirectUris =
             {
              "http://localhost:4200/",
             },
 
           PostLogoutRedirectUris = { "http://localhost:4200/" },
           AllowedCorsOrigins = { "http://localhost:4200" },
 
           AllowedScopes =
              {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                "api1"
               }
          }

Now your authentication mechanism is not vulnerable anymore against:
– interception and manipulation of the redirect URI
– Access token leakage through browser history or third parties

Leave a Reply