Hacker News new | past | comments | ask | show | jobs | submit login
Grammarly's OAuth Mistakes (fusionauth.io)
85 points by mooreds on Oct 27, 2023 | hide | past | favorite | 24 comments



Recent and related:

Oh-Auth – Abusing OAuth to take over millions of accounts - https://news.ycombinator.com/item?id=38009291 - Oct 2023 (110 comments)


Just say no to the implicit grant. OAuth 2.1 removes most of the foot guns in OAuth: https://oauth.net/2.1/


Hear hear!

I've been following OAuth 2.1 for a couple of years. Can't wait for it to get released. If you want to check out the IETF draft, here is the current version: https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...

Reading the "Differences from OAuth 2.0" section is helpful for understanding what changes are coming: https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...

You can also give your feedback on this or any other draft on the IETF OAuth mailing list: https://www.ietf.org/mailman/listinfo/oauth

I've been lurking there for a long time and learned a lot; you can view the archives here: https://mailarchive.ietf.org/arch/browse/oauth/


Hard to believe this isn't common practice at this point. Way back when I was just getting started in my career I implemented an OAuth 2.0 server and it was already accepted that auth code grants were the only reasonable way to do things. Here's what I wrote in the docs for that project:

    The decisions that are most important to the security of your application are:
    
    - The authorization endpoint will only return authorization codes, which can later be exchanged for access tokens.

    - Password credentials grants, implicit grants, client credentials grants, and all extension grants are not supported.

    - Public clients are not supported.

    - Every client is required to register its redirect_uri.

    - All authorization, token, and API requests are required to use TLS encryption in order to prevent credentials from being leaked to a third-party. In addition, the registered redirect_uri must also be secured with TLS.

    - Clients are required to CSRF-protect their redirection endpoints.
https://djoauth2.readthedocs.io/en/latest/overview.html#what...


As for the "hard to believe", consider this:

The guys who implemented this in the flawed way are probably at least twice as productive as the guys who'd thoroughly read the task and implement it correctly.


OIDC+OAuth is what most people actually want when they think of OAuth imo. The main issue here is that OAuth was not designed as an authentication protocol.


Aren't the exploits here in not checking that the access token calling you was for you? That is, it wasn't the implicit grant, it was not checking the audience/signature of the token?

What makes this an implicit grant problems?


Presumably, a confidential client identifies itself to the AS to exchange a code for an access token, so you know at that point that the access token was meant for that particular client.

That said, Facebook Connect is an under-documented vendor extension to OAuth, and only is supported for use via the official SDKs. They do now have a bit more alignment with OpenID Connect and PKCE as an option, but I imagine most existing parties do not use it. https://developers.facebook.com/docs/facebook-login/guides/a...


But wasn't this a case of the frontend client using harvested tokens from somewhere else?


The complexities of OAuth make me want to go solve an NTLM double-hop problem with a three headed dog.

Why are we seeing so many implementation mistakes? Is OAuth simply too difficult?


According to the lead author and editor of OAuth 2.0, (who asked that is name be removed from the spec) is: "a bad protocol."

Developer Quits OAuth 2.0 Spec, Calls It 'a Bad Protocol' - https://www.wired.com/2012/07/developer-quits-oauth-2-0-spec...

"OAuth 2.0 and the Road to Hell" - https://news.ycombinator.com/item?id=4294959


Strongly recommend reading this, as well as looking up Homakov's exploits. My opinion is that OAuth 2.0 is a very bad spec because in practice people do not implement it correctly. As to why? Maybe it's that the spec is split across multiple RFCs, and defines many insecure behaviors as compliant, and authorization is just hard.

When Facebook, Twitter, Github, etc. all got burned at various points in time with their OAuth implementations, you have to start looking for the common denominator.


> My opinion is that OAuth 2.0 is a very bad spec because in practice people do not implement it correctly.

Can we just stop using oauth entirely, then? There's got to be something better.


Oauth 2.1

> Keep in mind that when OAuth 2.0 was published in 2012, the iPhone 5 was brand new, the latest browser from Microsoft was Internet Explorer 9, single-page apps were called “AJAX apps”, and CORS was not yet an established W3C standard.


I think it's because

* it's a framework for authorization, with at least 8 different ways of using it (https://fusionauth.io/docs/v1/tech/core-concepts/modes has more)

* authentication is not most folks core competency


A big part is bespoke authentication on top of OAuth, rather than correctly implementing an actual standard to do such (OpenID Connect). OAuth is not an authentication protocol, it only gives guidance for delegated authorization.

OpenID Connect gives a mandated list of steps for verification.

Facebook Connect really only is supported via usage by an official SDK. If you are using an implementation that reverse engineered support for Facebook Connect rather than using the official SDK, you are on your own.


It's funnier when you know microsoft will abandon ntlm https://www.bleepingcomputer.com/news/security/microsoft-pla...


This doesn't seem to add much over the finder's blog post "Oh-Auth – Abusing OAuth to take over millions of accounts" (222 points, 110 comments, 3 days ago)[0] and the HN discussion (referenced in article), other than "use our software". As Salt Labs reasonably said "It's important to recognize that security vulnerabilities can arise (...) It’s the response that matters".

[0]: https://news.ycombinator.com/item?id=38009291


I'm an SE that helps software companies build integrations on top of the Prismatic platform and I've had the pleasure (or displeasure in this case) of building clients out to auth against a ton of different "flavors" of oauth.

We have a service that manages the exchange and refreshing of tokens for our customers and the number of unique implementations we're forced to support is mind boggling. I found it quite surprising how even some of the largest names in the industry have mangled their own implementations. Definitely not a "standard" in actual application.

It's clearly a difficult spec to implement, but I've witnessed that it's even more difficult for developers to learn and make use of when they're building out integrations to new systems. Unfortunately for most that do require supporting third-party integrations it becomes a necessary evil and one more burden for devs to manage and support.

I'm interested if others who have spent time dealing with a lot of third-party APIs have had similar experiences?


This is more OAuth's mistake than Grammarly's.

OAuth is frankly one of the very worst specs that I've tried to learn. Not just in the conceptual flaw of having so many types of flows (each with their own caveats), but in the opacity of the documentation (why use words like resource-owner/client/resource-server/authorization-server when user/browser/server/third-party would be more precise and reduce the learning curve), the reliance on the user to learn nearly the entirety of the spec just to use it properly (the main red flag of any framework or standard), and the way it ignores how it might be compromised in the implicit flow or via untrusted Javascript running in <script> tags (in fairness that makes most SPA grants security theater). All of this to replace the easily understandable concept of, say, a browser's session cookie.

I feel that there's too much wrong with OAuth to be fixed, that any new spec derived from it will also be terrible, and that any design-by-committee substitute will be just as bad. Leaving me no choice but to give OAuth a vote of no confidence.

Kind of ok but still terrible documentation:

https://www.digitalocean.com/community/tutorials/an-introduc...

You call this documentation?

https://auth0.com/docs/get-started/authentication-and-author...

A good replacement would handle all use cases without leaking any details about the implementation. Loosely that would look like the standard way of obtaining a security key and/or secret from the third party social provider and storing it in the backend server to access user details, filtered by whatever details the user chooses to share from the third party. If an SPA wants to be serverless, then a similar process must happen within, say, a P2P virtual server running a consensus algorithm like Raft or maybe borrowing blockchain concepts. IMHO this last part is still an open problem involving circles of trust, and is what has put this complexity on the shoulders of developers since roughly the mobile/social revolution that happened around 2007. All serverless stuff is either pretend (AWS Lambda) or a pipe dream without real P2P.

I also feel comfortable blaming OAuth for any factual mistakes I just made writing this.


https://oauth.net/2.1/

> OAuth 2.1 is an in-progress effort to consolidate and simplify the most commonly used features of OAuth 2.0.


Thanks! After studying OAuth 2.1, I think that the code challenge of the Proof Key for Code Exchange (PKCE/pixy) may fulfill what the Raft/blockchain/P2P concept I mentioned would do:

https://developers.onelogin.com/openid-connect/guides/auth-f...

https://auth0.com/docs/get-started/authentication-and-author...

https://oauth.net/2/pkce/

Unfortunately, I can tell that the people who write these articles don't actually know how the flows work at a deep enough level to speak about security ramifications. My mind immediately jumps to edge cases which aren't discussed, like this:

https://stackoverflow.com/questions/75341865/oauth-authoriza...

The whole point of PKCE is to allow a SPA/mobile/serverless app to obtain an access token without a client secret (since that could be leaked from Javascript or the device's filesystem).

But none of the tutorials explain how to use PKCE with a SPA and custom API server written in something like PHP, against a third party access token provider like Google. To me, if OAuth authentication happens through the API server, then the user has to trust that the API server acting on their behalf won't steal their data from the third party.

In an ideal world, I guess that the browser/device would perform all communication with Google and forward that response data to the API server.

But in practice, API servers usually facilitate OAuth flows to third parties, which leads to stuff like surveillance capitalism.

I don't expect to ever understand this at a deeper level, so will have to trust that whatever OAuth SDK I'm using is secure for PKCE. Including stuff like storing any tokens/codes as encrypted in any databases. I still can't shake the feeling that trusting OAuth involves drinking the kool-aid at some level.

TL;DR: OAuth with a custom API server acting on the user's behalf to communicate with a third party is no different than Mint being able to log into your bank account, so it's up to the API server to maintain good security standards. Unless OAuth happens entirely in the frontend app and it just forwards any third party data to the API server (which is rarely done), which still opens the user up to exploits in Javascript or the device's filesystem.


Why do you single out Grammarly in the title of this post when other larger orgs are part of this. I have no relation to Grammarly and I appeal to your fairness. Perhaps “Large organizations making OAuth implementation mistakes” would be more appropriate.


I wrote an OAuth 1.0a client to support getting access tokens from TripIt. I think I did this instead of using a library to (a) learn how OAuth worked, and (b) to deal with some oddities of TripIt's OAuth server.

Never again. OAuth is the worst.




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

Search: