Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To this day I have no idea how one should handle client secrets in (F)OSS applications, and I'm often wondering if I'm the only one. I guess what this text says in 4.13 is "just don't put it somewhere for anyone to see", which means that the only solution is to make the id and secret configurable and let the user register the application with its OAuth provider, which of course most users wouldn't know how to do. As a result, applications like Thunderbird simply put the secret in the code with a comment above it "please don't copy these values for your own application". I really don't mean to shame Mozilla, what else are they supposed to do?


It's not just an open source problem. It's fairly trivial to scrape the keys out of a lot of closed source applications. When Twitter first mandated OAuth, I was able to grep a key right out of the apk of their native Android client.

OAuth with client secrets is fundamentally unsuitable for desktop and mobile applications, but that hasn't stopped virtually every major implementor from using it that way. The people who wrote the spec were too busy congratulating each other and downplaying concerns to seriously engage with this issue until it was much too late to do anything about it.

It remains a deeply broken standard, and the people who were responsible for it at an early stage are entirely to blame. Several of them have removed their names from the spec, but I'll not forget the role they played in shouting down critics who raised concerns about this very issue.


Much of the deployment of OAuth2 was a shitshow, because early on, there was a huge debate about OAuth1 vs OAuth2, and the concepts and terminology used in the OAuth2 spec exceeded the mental load of people who were simply looking for a quickstart to some API. Docs by various providers either adopted the OAuth2 terminology wholesale without sufficiently explaining the new concepts and the best practices, or they simplified the client registration to just a few fields and offered no guidance as to make use of them in your app.

The spec has been clear from the start that there are clients that can protect their secrets, and ones that can't [1]. Here's a choice quote: "A native application is a public client installed and executed on the device used by the resource owner. Protocol data and credentials are accessible to the resource owner. It is assumed that any client authentication credentials included in the application can be extracted." Unfortunately, much of the rest of the spec is a bit like a playing puzzle, where reading it in one sitting doesn't actually build your understanding, and you have to constantly cross-reference various sections to construct a complete picture of the process the spec is trying to set.

It look a long time for people's familiarity with the spec to grow, and for providers and clients to improve in quality and adherence to the ideas and text of the spec.

[1] https://tools.ietf.org/html/rfc6749#section-2.1


If it's a FOSS clientside application, like a mobile or desktop app, it's a public application and the client secret doesn't really apply. If it's a serverside application, a web app, then every instance of the app will be registered independently with auth servers, and will manage their own client secrets.


From my understanding the best practice for applications that run on clients' machines (Javascript SPA, mobile app, email client) is to not use a client secret at all. Just use a client id and assume that anyone can reuse it.

Of course that is if the OAuth provider allows it.


Yup, a SPA can't really keep a secret, right?

That's why the best option is to set up a secure middleware layer to hold your secrets. Here's an example using react: https://fusionauth.io/blog/2020/03/10/securely-implement-oau...

(Full disclosure, this is a post on the blog of the companyfor which I work.)


People build SPAs with the OAuth2 code flow (and PKCE) all the time.


Sorry, I misspoke. Those SPAs always have middleware to handle the authorization code, right?

It's really the implicit grant (where access tokens are available to the client) that should be avoided.


No, with PKCE you can do auth code from an SPA


With the implicit grant? I read the RFC recently and thought it was only for the Authorization Code grant.

From https://tools.ietf.org/html/rfc7636

"OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy")."

At the end of the day, no matter what the grant, if you store the access tokens (or refresh tokens) in the browser running an SPA, it is vulnerable to an XSS attack, right?


This is solvable by use of a web worker as a key vault:

https://gitlab.com/jimdigriz/oauth2-worker


That is very cool, thanks for sharing!

Edit: This seems pretty new, any timeline for a release?


Thanks. I am not wholly convinced of the benefits of releases for a project of this scale, I suspect most will just reimplement the moving parts in their own code for a variety of (usually NIH) reasons.


With PKCE you can use the authorzation_code grant flow. The whole issue with SPAs and the authorization_code grant flow isn't the presence or absence of middleware; rather, it's the lack of a confidential client. PKCE gets around the requirement for a client to securely store it's secret.


Right, but even after the authorization code flow, the access token is stored somewhere on the client.

My understanding is that that is suboptimal because the browser has such a large surface area to secure.


> Of course that is if the OAuth provider allows it.

That's the catch. Last time I checked, at least Google didn't. So how can you write a (F)OSS email application for accessing GMail via OAuth2, without putting the secrets into the code (which Google also forbids)?


In this situation, their guidance says to embed the secret, because in this context it's obviously not a secret. Here's the current page [1]; here's the earliest Archive.org snapshot of its one-earlier predecessor page from 2015 [2] -- the advice has been consistent.

[1] https://developers.google.com/identity/protocols/oauth2/nati... [2] https://web.archive.org/web/20150520223809/https://developer...


No, Google is not consistent in the slightest, because their terms of service directly contradict this statement:

"Developer credentials (such as passwords, keys, and client IDs) are intended to be used by you and identify your API Client. You will keep your credentials confidential and make reasonable efforts to prevent and discourage other API Clients from using your credentials. Developer credentials may not be embedded in open source projects."

From: https://developers.google.com/terms


The conversation I had with a Google engineer implied the appropriate course of action was to embed the secret.

https://github.com/openid/AppAuth-JS/issues/46


The Google engineer should read Google's terms of service which explicitly states that you may not do that (see my reply above).


Google Mail's OAuth2 instructions discuss this point explicitly.


Have a link?


"The process results in a client ID and, in some cases, a client secret, which you embed in the source code of your application. (In this context, the client secret is obviously not treated as a secret.)"[0]

[0]: https://developers.google.com/identity/protocols/oauth2


You would not embed the client secret to any application unless you are open for public to see and use the secret (most likely not for applications you distribute to public domain).


Usually you put a service that hold the key, and the client application ask the service to do the request for it.

If the user doesn't want to use your service, they configure their own key.


Do you have any examples of this?


Isn't that what PKCE is for?




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: