[HN Gopher] Oh-Auth - Abusing OAuth to take over millions of acc...
___________________________________________________________________
Oh-Auth - Abusing OAuth to take over millions of accounts
Author : skilled
Score : 207 points
Date : 2023-10-25 04:57 UTC (1 days ago)
(HTM) web link (salt.security)
(TXT) w3m dump (salt.security)
| Spivak wrote:
| What am I missing here? How do you mess this up? Like you
| redirect to the OAuth provider with a url that has your client_id
| and ask for a postback and you get it with a code, you use that
| code _plus your app 's client_id/secret_ to get user-creds and
| then query some API to figure out who just authed. The code is
| tied to your client_id/secret. You have to implicitly verify the
| code you got just to figure out who logged in.
| michaeljx wrote:
| An attacker could call the post back with a code generated for
| another client_id. When you use the code to query who logged
| in, Facebook will still respond, even if the code was not
| generated for your client_id
| rosswilson wrote:
| This shouldn't be possible as the server-to-server request to
| Facebook to exchange the Authorization Code for an Access
| Token requires the client_id and client_secret to be
| provided. Facebook should (though I haven't actually
| confirmed this) verify that the code was issued to the given
| client_id. If the code was issued for client 123, when client
| 456 tries to exchange it for an Access Token Facebook should
| throw an error.
| jorams wrote:
| What you describe is the explicit grant flow and the exchange
| of the code for an access token automatically protects against
| this vulnerability. The bugs here are in the implicit grant
| flow where the redirect doesn't include an opaque code but an
| actual access token. There the application is responsible for
| validating that the token is for that application, but there's
| nothing that _requires_ it to do that.
| dboreham wrote:
| I'm a little confused about this. The article seems to say
| that the application (the server that is the target of the
| attack) makes a call to FB where the application believes
| that a successful response indicates that the user's
| credentials are valid. It says that FB responds with success
| (and the user's email). But in fact FB would respond with
| success regardless of whether the supplied token was valid
| (for that application). This seems like either a serious bug
| in FB's implementation, or very bad API design. Presumably
| it's the latter because FB is responding correctly to a
| request that has nothing to do with auth -- application
| (server) asked for the email for one of its users, providing
| its (the server's) credentials for that request. The problem
| is that the API doc/design has fooled the application
| developer into believing that that call was an auth check.
| But it wasn't.
|
| Is that it?
|
| Also...why is this not wrapped in a library such that it
| wouldn't be possible to make such a mistake?
| locallost wrote:
| "Facebook" (or whoever) just sends a token that says the
| user authorized the use of its account for the application.
| What happens in this 'hack' is that the token is valid, but
| was not actually intended for that application, but for
| another one (e.g. a malicious one, that is now trying to
| reuse the token to access other services of the same
| Facebook user). I don't know how Facebook tokens look like,
| but JWTs have a property called aud/audience indicating who
| the token was intended for. The application developer must
| verify that the token was actually intended for their
| application. That is my understanding, sorry if I got it
| wrong.
| dboreham wrote:
| I get that. You're not wrong. I'm asking _why_ Facebook
| tells the application anything other than "nope, that's
| not valid for you"? It doesn't seem to be a case of the
| application will accept random noise as a valid token. It
| does send the token to Facebook and Facebook responds
| with something that looks like "OK". But when they said
| "OK" they really meant "we gave you some valid
| information about the target user, but forgot to mention
| that the token you provided was not valid".
|
| I'm saying that Facebook should in all cases respond with
| "Nope, that's not a valid token". Their API just
| shouldn't have a way to get data on a user without
| providing a valid token (by valid, we mean valid for that
| purpose, not stolen from somewhere).
| locallost wrote:
| Because I guess in this "flow", you do not actually
| supply the information to Facebook for them to verify
| that claim. From the article:
|
| > In steps 6-7: > randomsite.com reads the token from the
| URL and uses it to talk directly with Facebook using the
| following API:
|
| > https://graph.facebook.com/me?fields=id,name,email&acce
| ss_to....
|
| > The response is john@gmail.com.
|
| So you send the token only and the token is valid, and
| there's no way for Facebook to check if it was meant for
| you or not. As mentioned in other posts, this would not
| happen in other flows because you would send e.g. your
| client secret along with the code.
| TazeTSchnitzel wrote:
| > Vidio, an online streaming platform with 100 million monthly
| active users, the researchers found that when logging into the
| site through Facebook, the site did not verify the token -- which
| the website developers and not OAuth must do. Because of this, an
| attacker could manipulate the API calls to insert an access token
| generated for a different application, the researchers found.
|
| How does this work? I thought the token was an opaque hex string
| and only had meaning when sent back to the original server?
| vladvasiliu wrote:
| IIRC, the user woud get an access token _from_ Facebook _for_
| the target site, e.g. Vidio. Vidio then has to make sure that
| not only is the token actually signed by Facebook, but also
| that Vidio is the token 's audience. The token shouldn't be
| opaque to Vidio.
|
| I'm in no way an authority on OAuth, but I think the "opaque
| token" you're talking about is in the situation when Vidio
| would want to access Facebook on the user's behalf: they would
| get an access token _for_ Facebook. The token can be opaque to
| Vidio.
| Incipient wrote:
| Not being a full expert on it either, that flow is roughly
| right. Vidio does have to validate it. The entire pkce flow
| is bloody painful to implement, and it's actually quite hard
| to do it perfectly, and easy to accidentally skip a part of
| it and have it seemingly work ok.
| tommiegannert wrote:
| The original article [1] explains it much further:
|
| > As you read previously, according to the Facebook
| documentation, when Vidio.com receives the access token from
| the user, Vidio should verify that the access token was
| generated to its App ID (92356) by calling the
| https://graph.facebook.com/debug_token API.
|
| Confirming what vladvasiliu said.
|
| 1. https://salt.security/blog/oh-auth-abusing-oauth-to-take-
| ove...
| arcastroe wrote:
| Gitea serves as an OIDC provider:
|
| * https://docs.gitea.com/next/development/oauth2-provider
|
| However, I don't see an equivalent API in gitea to the
| "debug_token" api.
|
| If I'm developing an application that allows "Login with
| Gitea", how do I make sure my application is not vulnerable?
| vladvasiliu wrote:
| See caseysoftware's reply:
| https://news.ycombinator.com/item?id=38022536
|
| The access token usually has an `aud` field that says for
| whom it is.
|
| I'm not familiar with Gitea's implementation, but reading
| your link, it would seem that it acts as an oauth2 provider
| so that 3rd parties can access _Gitea_ , not some other
| random app.
|
| > Gitea supports acting as an OAuth2 provider to _allow
| third party applications to access its resources_ with the
| user 's consent.
| caseysoftware wrote:
| The token _can_ be a opaque string but doesn 't have to be.
| Often, it's a JWT which can be decoded, validated, and used
| locally without a trip to the auth server.
|
| It looks like Vidio, etc validated the signature of the JWT
| properly but didn't check the "aud" or audience claim, which
| defines who should use it. Therefore, it was a valid token, it
| was for the target user, but the token itself wasn't for Vidio.
|
| It's the equivalent of buying a ticket for a United Airlines
| flight, going to the airport, and United letting you get on ANY
| flight because you have a valid ticket.
|
| _Background: I helped build the Okta OAuth product (not
| related to the breaches) and I 'm the author of the top
| OAuth/OIDC course on linkedIn._
| withinboredom wrote:
| Heh, this is exactly how I got on the wrong flight once (the
| gate changed and I didn't realize it), the machine didn't
| tell the person I was getting on the wrong flight and the
| attendant didn't notice.
|
| The only reason I discovered I was on the flight is because
| someone else had a ticket for my seat. The security people
| were very curious how I did it, both pilots were very pissed
| (both flights had to be stopped from leaving the gate until
| they were sure I didn't leave a bag on one of the flights,
| yay terrorism). But now you can't do that any more.
| magicalhippo wrote:
| Not just aud, but also issuer and you should check it was
| signed by a proper certificate no?
|
| https://learn.microsoft.com/en-us/entra/identity-
| platform/ac...
| vladvasiliu wrote:
| Indeed.
|
| In my case, I was initially confused by the fact that in
| most examples (specifically for Azure AD, which is what
| I've used), they give you an access token _for another app_
| , here MS Graph API. It specifically says you're not
| supposed to read that access token, so you can't validate
| it. You should use the ID token instead (which can be
| validated), but in the default configuration, the ID token
| doesn't carry much information, so you need to call the
| `userinfo` endpoint with said opaque access token.
| PeeMcGee wrote:
| For Microsoft it's another case of them going out of
| their way to exercise every possible inch of lee-way
| permitted by the specifications. No one in their right
| mind should expect a userinfo endpoint to only be
| accessible at an entirely different host. It's doubly
| stupid that Azure AD provides no other options for remote
| token validation, conveniently skipping the token
| introspection extension that _every other IdP supports._
|
| People writing OAuth2 clients reasonably assume that
| trustworthy IdP's will behave normally and predictably,
| which means Azure AD/Graph(/Entra ID?) is probably not
| compatible with the libraries you're using. Fortunately
| Microsoft provides their own perplexing, over-engineered
| SDK for a handful of languages. All you have to do is rip
| apart your existing OAuth2 plumbing and carve another
| Microsoft-sized hole into your otherwise nice and
| standardized application.
| vladvasiliu wrote:
| In my case, for apps that only need to authenticate users
| with AzureAD, I've added the required information to the
| tokens and called it a day.
|
| I wouldn't bet the farm on it, but I seem to remember
| that by default, the mozilla-oidc implementation for
| Django was expecting an userinfo-like endpoint. And I
| remember wasting an unbelievable amount of time trying to
| figure how to add information to that endpoint. I've
| never found anything, I just patched the lib to retrieve
| the relevant fields from the tokens.
| jillesvangurp wrote:
| Depends. The core issue is that a lot of developers confuse
| authentication and authorization. And oauth kind of muddles
| the water on that front by vaguely doing both but not
| really. All it does really is exchange tokens (assertions).
|
| Anything JWT related is orthogonal to oauth. Oauth does not
| actually provide any semantics for the tokens you exchange.
| They might be JWTs and you might be able to verify them. Or
| they might just be some random number, a hash, or some kind
| of database id. But you would have to know in advance what
| it is exactly and what the proper process for verifying the
| token is.
|
| In the case of a random number or some kind of session id,
| the process of verifying that token would involve looking
| it up from some kind of database or via some kind of API.
|
| Alternatively, with a JWT, it might be a signed one
| (hopefully) and you'd be able to check the signature if you
| have the public key. All you have at this point is a blob
| that was signed by someone that you might or might not
| trust. The claims and other meta data in the token would
| tell you hopefully who the person is (authentication) and
| the level of access they might be given (authorization).
| The JWT spec defines some fields that you might use for
| that. But it's up to you to check all those things and
| verify them.
|
| The point is, that a lot of this stuff is simply
| implementation/vendor specific and you just need to know
| what to check and how and why. And it's on you to do all
| those things.
|
| This is not an issue with oauth, or JWTs, but with
| incompetent developers doing things wrong or being
| lazy/negligent/indifferent. Which sadly is very common.
| Lots of people that get busy implementing all sorts of
| stuff without any formal training. And a lot of this stuff
| isn't even taught properly in schools/universities.
|
| This falls in the same category as putting passwords plain
| text in a database, not setting up ssl certificates,
| running your database on an open port on the internet, and
| similar things that developers do wrong all the time.
| Because they don't even know the basics of how to do things
| right. A lot of these things would be caught during any
| half decent audit. And quite a few of those things could
| expose the companies involved to some expensive law suits.
| Which is why lots of companies spend money on audits
| because they don't like expensive law suits.
| arka2147483647 wrote:
| Nope.
|
| The thing about cryptography you always hear being said
| is "don't roll your own crypto", because you don't know
| all the complexities and failure modes that experts have
| researched.
|
| In o-auth, just you comment mentions multiple ways of
| doing things, and different responsibilities the
| developers have in different circumstances. Essentially
| the developer is forced roll some of their own auth.
|
| Compare that, for example, to say how you use TLS. You
| just use the standard libs bundled everywhere, and open
| connection, and the the system does all the validation
| for you. The complexity is there, but average developer
| is not expected to understand it.
|
| O-auth simply exposes too many details to the average
| developer, and too many options to use them differently,
| for it to ever be secure.
| robertlagrant wrote:
| While what you say is true about OAuth2, this isn't what
| "don't roll your own crypto" refers to, I think. It's
| more like "don't start implementing crypto routines
| yourself".
| jillesvangurp wrote:
| That's just the way oauth works. I agree it's a messy
| protocol. Classic design by committee stuff. Exactly what
| you get when mutually incompatible security product
| vendors try to create a standard that covers what all of
| them do.
|
| Unfortunately, there are no good alternatives that don't
| have this problem. Basically people use all sorts of
| commercial products in the hopes that it will act like
| magic security pixie dust. Most of them are super
| complicated to work with. Or expensive. Or both.
|
| There's just no way around the fact that you need to know
| what you are doing and how stuff sticks together.
| withinboredom wrote:
| > incompetent developers doing things wrong or being
| lazy/negligent/indifferent. Which sadly is very common.
|
| I was code reviewing a dev who was implementing some auth
| and I mentioned they should log something for audit
| purposes. They said 'auditing isn't one of the
| requirements of this ticket' ... at which point, I knew
| it was time to leave. Like do you need someone to write a
| ticket to do your job? When people come ask "who logged
| in and deleted my org's content" ... you better have an
| answer. This is software engineering 201: logging.
|
| It's like an electrical engineer wiring a house not up to
| code and saying 'I don't care because the customer didn't
| ask for it to be up to code.'
| namtab00 wrote:
| I get what you're saying, but... Logging is not auditing,
| AFAIK.
|
| Also, and I may be very wrong based on the way that org
| prepared tasks, he may have been signaling scope creep...
| If it's not in the task, you don't do it. If you think it
| should be done, you backlog it...
| AckRite wrote:
| I agree with the comment above yours but also feel that
| this is... different style of work? Or attitude? Not sure
| how to name it but feels like I also brushed up against
| this numerous times.
|
| I assume that line of "what is scope creep and what is
| assumed to be in scope even if not written down" has to
| be blurry but I tend to judge people on which side they
| end up on, because I feel it correlates to indifference
| etc.
|
| Ultimately, it feels like a bad approach to work
| relationships - you actually have to do personal
| groundwork in your team to unblur the line to where you
| and your team agrees. And if that doesn't work out -
| leaving is a valid, if sad, option.
| withinboredom wrote:
| Not to be pedantic, but it's called an "Audit Log",
| usually. So, it is logging, though if you don't keep your
| logs forever, it is usually logged to a db or something
| (but that isn't necessary -- depends on the industry,
| privacy policy, etc.).
|
| > If it's not in the task, you don't do it. If you think
| it should be done, you backlog it...
|
| You shouldn't have to be told to do your job. One day,
| someone is going to ask why X wasn't done (when it
| clearly should have been, by all industry standards, and
| especially when it is exactly one line of code) and "I
| was just following orders" doesn't work in any court,
| including the ones that get you fired.
|
| When implementing auth, almost no PM is going to write
| down "mitigates timing attacks" as part of the acceptance
| criteria, but you do it anyway because it is the right
| way to do it.
| pixl97 wrote:
| And none of those things come down to the individual dev
| in any sizable organization I've ever seen. Suddenly
| you've started adding a db schema new db schema to the
| requirements and are likely blowing up the sprint.
|
| You push the ticker back up and fire off a few email to
| PM and ask what the hell they are doing with the
| requirements
| withinboredom wrote:
| Who said anything about db schemas? WTF are you talking
| about?
| phatskat wrote:
| > he may have been signaling scope creep... If it's not
| in the task, you don't do it. If you think it should be
| done, you backlog it...
|
| Correct. Especially if you're working for a client that's
| billing by hour. Regardless, new work changes scope and
| blah blah agile. Yes it's overhead, and it also creates a
| chain of who did what, and when.
| caseysoftware wrote:
| While what you're saying applies to OAuth in general,
| there are a lot less variables in this situation.
|
| This was specifically "Sign in with.." so we know it was
| OpenID Connect which mandates signed JWTs for ID tokens.
| Those JWTs would have an issuer (the social provider) to
| determine their source and the client id (to determine
| the intended app) so those aren't in question here.
|
| Further, since these are ID tokens, they WOULD provide
| authentication information (technically identity info)
| and minimal authorization info.
| caseysoftware wrote:
| The articles say these sites were validating the tokens -
| as in checking signatures - so they were doing that
| properly.
|
| The issuer is another matter. Facebook or any other social
| provider is different than using AD. With AD, every
| customer would have a separate and distinct issuer related
| to their specific org and config. For social auth, there
| would be ONE issuer that everyone shares.
| duttonw wrote:
| something something jwt token for implicit flow OAuth I'd guess.
| Incipient wrote:
| Should be pkce now. I think implicit flow is entirely dead? But
| could be wrong.
| duttonw wrote:
| it should be but auth0 was not forcing it to be off, just
| highly suggesting to turn off that 'feature' unsure now.
| duttonw wrote:
| Another option is pkce spa, if they did not do 'auth' checks
| that the jwt token was indeed signed by auth0 or similar, a
| carefully crafted js alteration would let you take control of
| the front end. Then you could give it a incorrectly signed
| token with all the correct details for another user. Usually
| they would only use the email for matching which makes things
| even more trivial.
|
| You would hope they verified the signing of the jwt token on
| the backend, but seems thats too difficult for many dev's.
| tansan wrote:
| PKCE should only be necessary if you're using app linking or
| have some client app in-between. If you completely trust the
| server than implicit is fine.
| krooj wrote:
| No. This is wrong. Implicit is deprecated in favor of
| authorization_code + PKCE
| krooj wrote:
| The important thing with PKCE is that it's not completely
| secure, either. A malicious actor can create an app that uses
| your client_id and its own code_challenge and verifier. In
| the event that there are any issues with redirect jacking,
| such as may be the case with custom schemes on mobile, you're
| hosed. The only way around this is to use intents (on
| Android) and OS pinning in the client configuration of your
| authorization server.
| geraldhh wrote:
| finally the "login as facebook" feature everybody has been
| waiting for
| 3abiton wrote:
| But this seems to require access to a different oauth token
| already, ie the victim could have had their tokens from other
| websites leaked.
| usrbinbash wrote:
| > But this seems to require access to a different oauth token
| already
|
| The article explans quite well how that works. The attacker
| makes an outwardly legitimate service, which is registered at
| the OAuth authentication provider, and waits for people to
| access it. All it has to do, is store the tokens on its
| backend, and try them, with the same username, against other
| services, using the same auth provider.
| davedx wrote:
| Another issue with OAuth is the assumption that the browser part
| of the flow (where the real user enters their username and
| password on the issuer website) is actually done by a real user.
| When I was trying to automate EV charging, I looked at quite a
| few OAuth implementations and many of them were doing things like
| storing the user's credentials (including their password) then
| doing the entire OAuth flow with browser automation. I imagine
| this was the tip of the iceberg.
|
| These days with a lot of non-standards-compliant OAuth
| implementations behind me, my conclusion is a lot of it is a
| giant waste of time, and it often adds completely pointless
| complexity for many of the cases it's used for. And as shown in
| the article, all the complexity often adds exploit vectors.
|
| For 90% of API use cases just issue a revokable Bearer Token and
| be done with it. You are not an app platform!!!
|
| [Qualifier: the EV API's I experimented with _were_ a good use-
| case for OAuth, as they were user-first, based on mobile apps
| authenticated with user /password credentials. But I've worked
| with a lot of third party vendor API's where it was purely
| server-to-server access, but for some reason wrapped in OAuth...
| because... architects and compliance something something]
| lathiat wrote:
| The oaith spec requires a callback URL to work and usually that
| url has to be "registered"/authorised with the server. Most of
| these apps are using the api "unofficially" and the only way to
| do that is with browser automation. Otherwise once the login is
| complete the redirect with the authorised token won't get to
| your app - it will go to the official website or app.
|
| They then pluck the authorised token out of the cookie store.
| davedx wrote:
| Not really. The libraries should do what my own app does:
| render the vendor website (Tesla or whoever) in a browser
| window and let the user enter their creds securely. You can
| then capture the auth code from the redirect just fine.
|
| There are right and wrong ways to do OAuth both in server and
| client, and many, many implementations do it wrong.
| randomdata wrote:
| _> You can then capture the auth code from the redirect
| just fine._
|
| Not when you don't have an 'official' redirect URL.
| codetrotter wrote:
| If you control the client, you can. Because when you get
| the redirect response, you then take the auth code that
| is included there, and you don't follow the redirect.
|
| Then you send the auth code to your backend instead.
| randomdata wrote:
| Typically if you farm the job out to a browser, per the
| discussion, then you don't have control over the client.
| codetrotter wrote:
| I took it to mean that they render the login page in a
| web view still controlled by their app
| davedx wrote:
| Right, so my app is an electron app, and you can hook
| into the redirect. It's still a little bit hacking the
| flow but not as bad as full browser automation
| lathiat wrote:
| That works for GUI apps I agree though doesn't work for
| server side stuff. Which I suspect the software the OP
| meant is. But yes better than storing the password if you
| are on a desktop.
| Semaphor wrote:
| > it was purely server-to-server access, but for some reason
| wrapped in OAuth... because... architects and compliance
| something something]
|
| That sometimes feels like the bane of my existence. Everything
| has to be OAuth and use refresh tokens, certificates etc. when
| I never care or use any user data. No one logs in. This is all
| our server talking to their server. Revokable Bearer Tokens
| used to be used, but every API that updates switched to OAuth
| which makes everything more complicated.
| krooj wrote:
| This is what the client_credentials grant flow is intended
| for. If you're using any interactive grant flows to secure
| S2S communications, you're doing it wrong.
| figassis wrote:
| What I hate about OAuth is how slow and cumbersome it makes the
| process across the web. Everything requires login with google
| for example, but that flow is so slow that it's what I dread
| the most of all auth. Especially when I see the page reloading
| multiple times because it wants so many other things besides
| just auth.
| PH95VuimJjqBqy wrote:
| If you have an IAM with underlying IDP's it will legit be a
| stack of redirects with callbacks, sometimes deeper than 1 or
| 2. It's nuts.
| caseysoftware wrote:
| > _I 've worked with a lot of third party vendor API's where it
| was purely server-to-server access, but for some reason wrapped
| in OAuth... because... architects and compliance something
| something_
|
| As someone who's implemented a bunch of these..
|
| It's less about compliance and more about getting everything
| "speaking OAuth"
|
| Once you've converted your user-facing flows to use OAuth and
| you're dealing with scopes, tokens, etc, converting the backend
| to also use it makes a lot of sense. Then you have ONE path for
| token validation, inspecting/validating scopes, and client
| id/secret issuance whether you're on the front or back end.
| Having one model for people to understand makes things tangibly
| simpler and shrinks the libraries/tools you need.
|
| If you ONLY have backend (service to service) flows with a
| simple authZ model, OAuth is usually overkill.
| PH95VuimJjqBqy wrote:
| OAuth is usually overkill, period.
|
| There are only two real use cases for the complexity of
| OAuth.
|
| 1. SAAS model and you're allowing your customers to use their
| own IDP
|
| 2. You really and truly have a lot of disparate internal
| systems that need SSO.
|
| And 2 generally has better solutions.
| sleepybrett wrote:
| > And 2 generally has better solutions.
|
| you fail to mention them.
| PH95VuimJjqBqy wrote:
| because it depends on the specific needs. It could be as
| simple as LDAP integration or as complex as OAuth.
| marcosdumay wrote:
| One really shitty thing is that people keep inventing
| those badly-though protocols like OAuth, and yet nobody
| (as in no browser) ever implemented LDAP over the web.
| pixl97 wrote:
| Isn't ldap in the browser just something like NTLM?
| marcosdumay wrote:
| Negotiate uses the OS LDAP tokens on the web.
|
| Windows has that stupid rule where LDAP runs all over the
| OS or nowhere at all, and Linux has that idea that LDAP
| is some add-on you assemble by connecting a jigsaw of
| pieces. Nothing makes it reasonable to publish a domain
| on the web, where people can authenticate on many of
| them, and send the tokens where needed.
|
| (Well, actually Firefox does most of it, and you can use
| it and assemble the Linux pieces so it works. It just
| doesn't work in practice.)
| Spivak wrote:
| Look I'll sing LDAP's praises when it's appropriate but
| this really isn't it. It's less of SSO and more "Same
| Password Everywhere" which are not at all the same
| experience from the user perspective. It also teaches
| your users to plug their creds into random login screens
| instead of the one-true-login-page they can verify is us.
|
| Like as hackers we make fun of the phishing training that
| teaches you to avoid sketchy links in emails while
| simultaneously the real emails have the sketchiest links
| of all time. Using LDAP for this use-case is our version
| of that.
| caseysoftware wrote:
| ^ This.
|
| We should teach users to put their passwords into very
| few, limited, and trusted places. The cool new social app
| is NOT trusted. That random app on your phone is NOT
| trusted.
|
| There's even an xkcd on this one: https://xkcd.com/792/
| pmontra wrote:
| That xkcd is about the downside of using the dame
| password on many services. No service is really trusted
| so what we should teach people to do is, as usual, to use
| a password manager to randomly generate a new password
| for every service. Maybe that's what you were advocating
| but it was not clear to me.
|
| We should also teach to ourselves to throw away all those
| weird rules about passwords, like 6 to 15 characters max,
| letters and digits and a random set of punctuation
| characters liked by the site owner. Why those limits when
| they are storing a hash anyway?
| PH95VuimJjqBqy wrote:
| name something that doesn't have downsides.
|
| go on, I'll wait.
| iimblack wrote:
| Yikes ignoring that there can be different severity and
| type of downside
| PH95VuimJjqBqy wrote:
| somehow "depends on the specific needs." got turned into
| "ignoring different severity and downsides".
|
| Who knows what goes through people's heads.
| sleepybrett wrote:
| Well lets talk about your average 'bigcorp'. You've got
| laptops you need to log into, you've got network shares
| you need to log into, you've got internal web
| applications you need to log into, you've got external
| saas bullshit you need to log into, you have some cloud
| accounts you need to access... You need to manage this
| for thousands of people, probably 10s of thousands of
| people.
|
| You don't want your average user to have a great many
| usernames and passwords, maybe two or three at most to
| manage. You also probably don't want to have them share
| those credentials.. though without 'one big system' you
| can't really prevent that. You also probably want some
| kind of system with 2factor support through a few
| different methods, rolling code, sms, yubikey, etc.
|
| LDAP ain't it.
|
| From where I set Oauth seems to be the current solution
| with the least number of downsides. It's complicated for
| sure, the flows are easy to fuck up, but I haven't seen a
| better solution.
|
| Maybe Passkey is it, i keep meaning to read the rundown
| but I just haven't found the time... and also it's
| realativly new enough that support and open source
| solutions might be a little sparse...
| PH95VuimJjqBqy wrote:
| To hear you describe it, SSO didn't exist before OAuth.
|
| And yet it did.
| marcosdumay wrote:
| > because... architects and compliance something something
|
| At work the tooling we use for our services outright requires
| OAuth if you want authentication. And yeah, that's a large
| factor implying we should use something else, but there are
| many coordination problems for that.
|
| I imagine plenty of people have a similar problem.
|
| Anyway, if your client is saving your password, then I'd say
| that's not a good use-case for OAuth. At this point I'm not
| sure there exist a good use-case for OAuth.
| judge2020 wrote:
| Tesla only just recently opened the ability to be an official
| oauth application, so all apps before now either required
| storing username+password or the long-lived token it sends back
| once you authenticate.
| mgaunard wrote:
| Or you can just use JWT which instead of asking the identity
| provider whether a token is valid simply requires you to check
| its signature against a public key.
| camkego wrote:
| Some of the vulnerabilities in the article are due to
| validating the signature of the JWT properly but not checking
| the "aud" or audience claim. Honestly, I would be tempted to
| call back to check the token due to how easy it is to make a
| mistake with JWT.
| mgaunard wrote:
| Of course, it just checks that the token was indeed generated
| by the identity provider. You still need to check that its
| contents match what you expect for your application.
|
| Issuing a request to another server from my backend would be
| a non-starter, completely incompatible with any sensible
| performance or security model.
| mooreds wrote:
| > it just checks that the token was indeed generated by the
| identity provider.
|
| This! I have given a talk on JWTs dozens of times and
| always emphasize that you must do two things:
|
| * verify the signature
|
| * validate the claims (including standard ones like `aud`
| and non-standard, business specific ones)
|
| You must must must do both to securely trust the token.
|
| This isn't just a JWT thing, either. If you provide a token
| to an introspect endpoint like what Facebook provides, only
| the first item is taken care of. You must still inspect the
| claims.
|
| Libraries will sometimes help with the standard claims, but
| you're on your own for non-standard ones.
| 29athrowaway wrote:
| tl;dr: it was an open redirect.
| talkin wrote:
| No, it wasn't.
|
| It's not validating reused codes or tokens from an application
| owned by attacker.
| 29athrowaway wrote:
| True, thanks for noticing. I re-read it more carefully
| bjt12345 wrote:
| .
| raselhanout wrote:
| > OAuth also uses an "explicit grant type," which is similar to
| "implicit grant type" but the server (randomsite.com) receives a
| code instead of a token and needs to make an additional request
| to Facebook to exchange it for a token. We're using the implicit
| grant type example here because it is easier to understand and
| relevant to this post.
|
| Are the first two attacks possible with explicit grant ? Wouldn't
| the auth server return an error if the client tried to request
| the access token with their secret and the code from another
| client ?
| sigwinch28 wrote:
| No, they're not possible. Yes, the auth server would return an
| error because the token is retrieved by the server out-of-band
| (Mallory can't intercept via the browser) and must provide its
| credentials to Facebook to retrieve said token.
|
| Additionally, Facebook SHOULD check that the client using the
| code is the same client that initiated the OAuth flow.
| agentultra wrote:
| Securing an OAuth implementation is hard. There've been several
| appendices added to the spec that many developers are probably
| not aware of [0]. Remember to check for current best practices to
| learn about the latest mitigations and protocol updates!
|
| [0] https://www.ietf.org/id/draft-ietf-oauth-security-
| topics-24....
| vinckr wrote:
| You probably dont need OAuth2/OIDC. While the two are very
| powerful protocols when used correctly, and have many advantages
| and use cases, the truth is that they are not always necessary.
| In fact, you most likely do not need them.
|
| - https://www.ory.sh/oauth2-openid-connect-do-you-need-use-cas...
| kriops wrote:
| I don't disagree, but I want to expand upon your point in a
| cautionary direction: Using OIDC/OAuth2 does prevent you from
| making several classes of rudimentary mistakes, entirely for
| free. The nonces and whitelists aren't there just to look
| pretty!
| fastest963 wrote:
| You can send appsecret_proof instead to validate the token and
| the app. See https://developers.facebook.com/docs/facebook-
| login/security...
| nstart wrote:
| Hang on... So this means that when I check the token as per the
| guide at https://developers.facebook.com/docs/facebook-
| login/guides/a... , it returns the information regardless of the
| access_token parameter matching the app id or not? My assumption
| without reading the docs would have been that if the input_token
| was from another app, FB would refuse to debug it if the
| access_token was not associated with the app id.
|
| What's the point in asking for the access_token at all for that
| endpoint otherwise?
|
| Am I misunderstanding the bug? This feels like a foot gun that
| was happily handed over to a lot of people all this time.
| wunderwuzzi23 wrote:
| Don't forget about ROPC!!
|
| There is also an MFA bypass that I see often, it's the Resource
| Owner Password Credentials (ROPC) flow in OAuth.
|
| Especially when you have an Microsoft M365/Azure tenant. Pretty
| much every client that I have ever tested had this issue. When
| ROPC is configured (which is the default) then you can just use a
| simple password to logon (and it bypasses MFA).
|
| More details and a tool to test your own tenant:
| https://embracethered.com/blog/posts/2022/ropci-so-you-think...
|
| If you use M365/Azure test and see if you can logon without MFA,
| you might be surprised.
| charles_f wrote:
| > the OAuth protocol itself is indeed correctly designed and is
| secure by nature. However, to use it with a web service requires
| integrating it into that service's existing platform, which is
| where the trouble starts
|
| That's my main beef with OAuth. I like having a standard in the
| middle, I also like OAuth, and I think I understand some of the
| flows well (I have enough knowledge to know I'm not an expert).
|
| The main issue is that it is complex enough that you can botch
| the implementation in multiple places (eg misuse of the
| refresg_token), flexible enough that you can take the wrong
| shortcuts (eg use the wrong flow), and most implementations have
| semi-transparent intermediary points (eg Jwt that you can see
| into) that make you feel like you understand the whole thing
| while you only get half of it - or once again use a component for
| something it should not be used (id_token for authorization being
| the most common).
|
| It's better than inventing your own scheme, which is certain to
| fail. But most people don't spend or don't get the time they need
| to understand properly. It doesn't result in gaps necessarily,
| but it can.
| candiddevmike wrote:
| You can use your existing API tokens as the OAuth access_token.
| Refresh tokens are optional. None of it has to be a JWT. Doing
| this prevents having to support multiple API auth methods.
|
| OIDC on the other hand...
| charles_f wrote:
| That's precisely the point. You _can_ do those things, or you
| can _not_ do them. And there are paths in the combinatorial
| that leave you with an open door.
|
| Re: OIDC, that's yet another one. The average dev can't tell
| you the difference between both - or won't even know the term
| OIDC and call it OAuth.
| foxyv wrote:
| I recently implemented some code to: Sign into an account using
| username/password/MFA, authenticate with an API using OAuth to
| get a SAML assertion, authenticate with another API using the
| SAML assertion to get a token, then sign into an API using the
| token...
|
| Why do we do this to ourselves?
| jeroenhd wrote:
| Not having to deal with auth yourself makes your life so much
| easier.
|
| For my self hosted stuff, I've out a simple OIDC requirement in
| my Apache config (https://github.com/OpenIDC/mod_auth_openidc)
| and have set up a plain Keycloak server (should've gone with
| something simpler but oh well). Apache now sets the user ID in
| a header (that doesn't get passed on from the client for
| obvious security reasons) and all the application on the other
| end needs to do is look up the user ID. Multi factor
| authentication, password recovery, session expiration and
| everything else is all handled by Keycloak and no
| unauthenticated requests can make it through Apache. Tokens are
| signed and verified, of course, so there's no faking anything.
|
| I think Caddy has a similar system built in, including a login
| page and everything. Give or six lines of config are all you
| need to handle authentication, plus you get automatic security
| updates for your authentication flow in case something happens.
|
| There's a reason Okta and its competitors are selling auth as a
| service: doing auth yourself properly is a massive pain that
| you need to stay on top of. You need to set up secure hashes,
| integrate TOTP/FIDO2 with appropriate recovery mechanisms, set
| up login flows, deal with session expiration, and all that
| stuff, when all you want is "give me a user ID so I know what
| data to load".
|
| These systems are annoying to develop against (though plenty of
| libraries are available to do the hard parts for you) but
| they're great if you just want to secure a backend or web
| application.
|
| I don't know why you needed two extra assertions when you were
| already authenticated, though. That's sounds like bad
| integration to me.
| foxyv wrote:
| Signing into AWS API through OKTA using a SAML Identity
| Provider. Just the way it was implemented unfortunately.
| OKTA's API is okay for this sort of stuff, but they need a
| SAML Assertion API that doesn't require scraping HTML. Also
| it would be nice if their JSON formatting weren't so all over
| the place.
|
| So it went: OKTA Assertion -> OKTA SAML Assertion -> AWS STS
| Token
|
| > That's sounds like bad integration to me.
|
| No arguments here.
| fulafel wrote:
| Are these cases all implicit flow, except the Grammarly case
| where a bug/misconfiguration made it accept the implicit flow
| param anyway?
| Foobar8568 wrote:
| I read a lot of things in oauth, implemented several Saas/API
| access for server to server communication, and I feel it's so
| insecure that I am sure I have missed something...
| krooj wrote:
| This article is not as impressive as one might imagine - the
| exploit appears to use the implicit grant flow, which is
| officially deprecated and should be replaced by the
| authorization_code + PKCE flow.
| gerardnico wrote:
| It should not happen if you have a proper state that is local,
| unknown from the attacker and temporarily valid.
|
| https://datacadamia.com/iam/oauth/state
| woranl wrote:
| Which version of OAuth implementation is at risk? 2.0 and 1.0a
| are quite different.
___________________________________________________________________
(page generated 2023-10-26 23:02 UTC)