Using Google OIDC with code flow and PKCE
Asked Answered
K

4

25

after trial and error it seems to me that Google OIDC does not support the code flow without supplying the client secret: https://developers.google.com/identity/protocols/oauth2/native-app#exchange-authorization-code

According to the latest best practices for SPAs (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13), code flow + PKCE is the recommended way to handle authentication. Is anyone aware of any trick required to make Google's code flow accept the code_challenge rather than the client_secret? Perhaps a dummy secret?

Katrinka answered 17/3, 2020 at 14:45 Comment(1)
I have also issues with the "client_secret" right now. So I opened an issue at Google to give it some attention. Any support on this would be welcome. The main issue is that the accounts.google.com/token endpoints requires us to send the client_secret for Web Clients. issuetracker.google.com/issues/184351769Lapland
I
19

As of August 2020 the best practices document cited is still in draft and being activly updated - head revision here: https://datatracker.ietf.org/doc/draft-ietf-oauth-security-topics/. Googles' OAuth2 implementation has not yet applied the "work in progress" recomendation of PKCE being applied to web applications. SPAs are still directed to use the implicit flow in Googles' online documentation: https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow).

The standard for PKCE (https://www.rfc-editor.org/rfc/rfc7636) details that it was developed as a mitigation for authorisation code interception attacks found on mobile platforms and was originally recommended for implementation by native clients. Google's documentation for "Mobile and Desktop apps" does direct developers to use a PKCE Authorization Code flow. Clients using Google Android, iOS or windows store credential types with PKCE may omit the client_secret (see the note on the refresh token parameter table - and confirmed by Cristiano).

It is now recognised that PKCE eliminates the need for any public clients to store a client secret, and as such can be used to deprecate the implicit flow which always had the flaw of including returned access and identity tokens in a redirect URI. https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead.

The draft IETF document states in section 2.1.1 that this recognition is likely to become a published standard.

Hopefully Google will update its implementation to remove the requirement for a client_secret for a PKCE token request when the best practices becomes accepted. In the meantime it seems we have no choice but to continue writing SPAs using the implicit flow.

Internuncio answered 6/8, 2020 at 1:16 Comment(11)
Ridiculous, I couldn't believe your last passage. But it's true?! developers.google.com/identity/protocols/oauth2/… Says "Google supports [PKCE] to make the installed app flow more secure". But I can't do Google OIDC using PKCE without a client secret. Google forces me to have a secret on my client and that can always be stolen, see: developer.okta.com/blog/2019/01/22/…. Completely removes any security benefit PKCE provides? Please tell me I'm wrong.Wed
I'm at least partially wrong. PKCE is still secured imo. But I'm not sure what happens if you have multiple apps with different flows for one registered Google api/application. If your PKCE app exposes the secret, are other apps with other flows still secure?Wed
Has anything changed in this regard? I cannot find anything to say otherwise.Laure
@Wed yes that's the point of PKCE ... the 'client secret' is not considered to be secret. Whether Google forced you to provide one or not, it isn't ultimately trusted. Though it might at least force a little more effort on the part of an attacker ... that is to say, if the client-secret is actually wrong, then sending a 4xx status code ASAP consumes fewer resources than going though the whole charade until it's discovered the PKCE is also wrong. So think of it as a fast-fail anti-abuse requirement.Dehnel
@DavidBullock What do you mean the 'client secret' is not considered to be secret? Sure, the attacker needs access to more resources in addition to the secret to cause harm, like a valid redirect URI, but that's another topic. In any case, the Oauth2 specs clearly say that the secret should not be exposed. Whether or not you use a dummy secret is irrelevant, it's still a valid secret.Cockloft
@Cockloft For installed apps, you likely 'distribute the app binary' (eg. via an app store) and now any party with your binary has your app's 'client_secret' and 'client_id' in their disassembler. For websites ... the client-secret stays on the server-farm, no prob. But an installed app doing an 'authorization code' flow without PCKE risks a hostile app on the same device intercepting the 'redirect', then using the client-id/client-secret of YOUR app to exchange the code for an access token. With PCKE, it must also prove it was the one to initiate the OAuth request before getting the token.Dehnel
@DavidBullock I know how PKCE works and its benefit, that's not what I'm asking. To reiterate what I said in my last comment, I'm asking what you mean by "the 'client secret' is not considered to be secret"? It's a secret; it should not be exposed. Ever. As per Google's docs, you are required to provide the code_verifier when doing the flow with PKCE as well as the client_secret, thus completely defying the point of PKCE...which is to not have to provide the secret.Cockloft
@Cockloft but the point is that if you distribute the app binaries, the client_secret is now 'not very secret'. Every copy of the app must necessarily have 'the application client_secret' baked-in. It might be obfuscated, sure. But the 'secrecy' in the sense that only Alice and Bob know what it is, is gone. That's why RFC 7636 says "Secrets provisioned in client binary applications cannot be considered confidential" (Section 1, 3rd numbered-list-item). datatracker.ietf.org/doc/html/rfc7636Dehnel
@Cockloft I'm also saying that a 'null client_secret' and a 'client-secret with high entropy' are both equivalent, when PKCE is used. Some Authorization servers (eg. Xero's) which use an authorization code with PCKE flow don't even allow you to supply a client_secret when you register your PCKE-app with the authzn_server. That Google requires a client_secret even when using PCKE is unnecessary and annoying of them. But only in a minor way.Dehnel
Any update on this? Is it better to use PKCE and store the client secret on the client or use the implicit flow? My client is a Chrome Extension.Braid
I would never public a client secret in a packaged binary. That would be insanity! Easily reverse compiles / analysed with a hex editor, etc.Bodega
A
2

Well, I'm using openId Connect authorization code with pkce without using client_secret in an android app using this lib: https://github.com/openid/AppAuth-Android.

I just had to ensure that the custom scheme was set using the app's package name from the manifest and use it to register the android credential on google console.

Amnion answered 7/4, 2020 at 20:47 Comment(1)
But you're not using Google OIDC?Wed
W
2

A good alternative IMHO consists in using Keycloak as IDP and then adding Google to the delegate identity providers of your Keycloak instance (and then Facebook and then any other idp if required). Keycloak implements the PKCE flow or whatever flow in the Oauth 2 RFCs in a reliable way. That means you need a hosted instance of Keycloak though.

Wheat answered 18/9, 2021 at 21:52 Comment(0)
B
0

Note that google on it's OIDC configuration enpoint mentions that it supports both plain and S256 as PKCE code challenge methors. I just tested using the code flow in google using both the client secret and passing the code_challenge and code_verifier in the relevant oath steps.

Here my observations at the time of writing

  1. The client secret is still required as mention by the OP, otherwise google starts complaining about a missing field.
  2. Google supports PKCE flow if you send your client secret. To be more precise
    • If you pass a code challenge and a valid code verifier then you get your token from the token endpoint
    • If you pass a code challenge and an invalid code verifier to the token endpoint then you get an invalid_grant error.

For completeness this is the error message that you get if you use the code flow with client credentials and invalid code verifier:

{
  "error": "invalid_grant",
  "error_description": "Invalid code verifier."
}

So you can use PKCE for extra security if you just send the code challenges and verifiers together with the client secret.

Brettbretz answered 1/12, 2023 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.