[HN Gopher] OAuth 2.0 Authentication Vulnerabilities
___________________________________________________________________
OAuth 2.0 Authentication Vulnerabilities
Author : lobo_tuerto
Score : 98 points
Date : 2021-03-27 16:04 UTC (6 hours ago)
(HTM) web link (portswigger.net)
(TXT) w3m dump (portswigger.net)
| vwpolo3 wrote:
| The first vulnerability is in the title, OAuth is an
| Authorization framework (Open Authorization) and is explicitly
| NOT for authentication. It's also a delegation protocol (I give
| you something to do on my behalf).
|
| If you want a list of things that can go wrong, look here:
| https://tools.ietf.org/id/draft-ietf-oauth-security-topics-1...
|
| Generally you probably do not need OAuth2:
| https://www.ory.sh/hydra/docs/concepts/before-oauth2/
|
| But if you do don't roll your own but use proven open source like
| https://github.com/ory/hydra
| oauea wrote:
| Nice, that page and your post is basically an ad. You don't
| need a proven open standard, you need our custom protocol
| instead!
| vwpolo3 wrote:
| It explains why OAuth2 is hard to use and does not solve
| login, registration, sessions, profile management, mfa, and
| proposes another solution. It's all open source! :)
| pmh wrote:
| From a quick glance, it doesn't look like a protocol per se,
| but a user management system akin to Keycloak. Those solve a
| slightly different set of problems than OIDC or OAuth
| Osiris wrote:
| Your first link calls the specification "Open Authentication"
| which seems to contradict your statement that it's called "Open
| Authorization".
| vwpolo3 wrote:
| That looks like a mistake in the doc:
|
| - https://oauth.net/articles/authentication/
|
| - https://tools.ietf.org/html/rfc6749 - The OAuth 2.0
| Authorization Framework
| iecheruo wrote:
| From the article:
|
| > OAuth authentication
|
| > Although not originally intended for this purpose, OAuth has
| evolved into a means of authenticating users as well.
| ddek wrote:
| The OAuth 2.0 RFC specifies the 'password' grant type, where
| the user provides the username and password directly.
|
| I'd contest the claim that OAuth was not intended for
| authentication, because there are no authz uses for the
| password grant.
| UncleMeat wrote:
| In fact, there id say that the huge majority of oauth flows
| on the web are used for authentication at this point.
| based2 wrote:
| -> OAuthz (vs authn)
| k__ wrote:
| Interesting, I always thought it was the other way around.
|
| It would authenticate who you are, but you have authorize the
| people yourself later.
| babelfish wrote:
| OpenID Connect is built on top of OAuth2 and is the
| recommended solution for authentication.
| mooreds wrote:
| It is designed for authorization but as sibling comments have
| said, it is very often used for authentication. Even though
| good old RFC 6749 says nothing about the details of
| authentication and leaves the nitty gritty of that to the
| Authorization server. But almost every OAuth server I'm aware
| of has some kind of authentication functionality.
|
| 100% agree that you should not roll your own. There are lots
| and lots of options out there with different strengths and
| weaknesses. Determine what you need and then find the right
| solution (which may be hydra or something else).
| waynesonfire wrote:
| You had one job...
| mooreds wrote:
| Great post. I work in the space and am coming up to speed on some
| of the security issues.
|
| Comments:
|
| * this is a great read about security and OAuth:
| https://tools.ietf.org/html/draft-ietf-oauth-security-topics...
| written by experienced folks.
|
| * don't use the implicit grant, please. Use the authorization
| code grant with PKCE. Here's an example (from a doc I helped
| write, talking about how bad the implicit grant is:
| https://fusionauth.io/learn/expert-advice/oauth/modern-guide...
|
| * State can be used for CSRF protection but I've also seen it
| used to convey, well, state that needs to be carried over. That's
| legitimate, but make sure you append a random value as suggested.
|
| * The well known endpoints will only be present if the OAuth
| server supports RFC 8414: https://tools.ietf.org/html/rfc8414 but
| you can always check the documentation. Most OAuth servers have
| plenty of public documentation to make their usage easier.
|
| * Re "Flawed redirect_uri validation", the OAuth 2.1 spec has
| tightened this up some and wants exact URI matching. We have some
| customers who want wildcard matching, but the redirect_uri check
| is a fundamental part of the OAuth security architecture, so
| we've resisted that request.
|
| * "However, by stealing an OAuth code or token, the attacker can
| gain access to the user's account in their own browser." is a
| good reminder that you should keep your token lifetimes short. We
| recommend minutes; use a refresh token to renew the token.
|
| All in all, thought provoking article. There's a reason why more
| and more teams are outsourcing auth; there's a lot of flexibility
| in the specs and it's easy to make mistakes. Even when you do it
| right the first time, there's ongoing maintenance. You should run
| a bug bounty program and/or regularly pentest your system.
| zemnmez wrote:
| > don't use the implicit grant, please. Use the authorization
| code grant with PKCE. Here's an example (from a doc I helped
| write, talking about how bad the implicit grant is:
| https://fusionauth.io/learn/expert-advice/oauth/modern-guide...
|
| This is a bit of a strange security model. The implicit grant
| vulnerability mentioned is essentially a supply chain attack
| where an untrusted library is loaded. True, it can compromise
| the implicit grant token, but, in a mode where the implicit
| grant token is hidden, it's still talking _as_ the website, and
| can do ~most~ anything, more or less that the token can do by
| making a request with the cookie, or whatever.
| tftyeti wrote:
| Probably a silly question, but how exactly does the refresh
| token help here? If your app is keeping the tokens accessible
| from javascript, then an attacker who (through XSS for example)
| can steal the short-lived access token could also steal the
| long-lived refresh token an "trade it" for a new access token,
| no?
| windowsworkstoo wrote:
| Refresh token rotation seems to be the standard mitigation
| (https://auth0.com/docs/tokens/refresh-tokens/refresh-
| token-r...)
| tftyeti wrote:
| Sure, that mitigates the risk when an attacker finds a
| refresh token later and it's no longer valid because of
| rotation. And it means that a stolen refresh token would
| probably be noticeable because the legitimate user wouldn't
| be able to use it anymore. But in many attack scenarios the
| attacker would get the refresh token immediately and the
| time until discovery would be enough for them to cause
| damage, right?
| tiziano88 wrote:
| Usually the refresh token would be kept server side only
| progre wrote:
| Regarding the access token...
|
| > the server does not have any secrets or passwords to compare
| with the submitted data, which means that it is implicitly
| trusted
|
| The access token should be signed right? So it's _not_ implicitly
| trusted. The server must of course validate the access token
| using the public key indicated in the token, and of course only
| accept tokens from trusted providers. Maybe I 'm not reading this
| right.
| jayd16 wrote:
| >As a result, this behavior can lead to a serious vulnerability
| if the client application doesn't properly check that the
| access token matches the other data in the request.
|
| Later they use this language the clarify the situation. I
| suppose the situation being described is when the token has no
| information that can track to a specific user id. I guess devs
| are just checking that a token decrypts and aren't verifying it
| matches the user id in the request?
|
| Seems like basic security 101.
| mooreds wrote:
| That whole section is about the implicit grant anyway, which
| should be avoided.
|
| As far as validating tokens, access tokens are 'opaque' in
| OAuth2; the token format is not defined by the spec. (In OIDC,
| they are JSON web tokens.) For OAuth, you can make a call to
| the introspect endpoint and the Authorization Server will tell
| you if it is a valid token.
|
| In practice, OAuth servers often issue JWTs, and there's a
| draft spec out to make them interoperable:
| https://tools.ietf.org/html/draft-ietf-oauth-access-token-jw...
|
| If you are a resource server consuming an access token and you
| know the token is a JWT, you should check the following at a
| minimum: * the token is signed according to
| the algo and the key that you expect * the token is not
| expired (the `exp` claim) and is currently valid (the `nbf`
| claim, if present) * the token is issued by who you
| expect (the `iss` claim) (which is the point you are making
| about 'trusted providers') * the token is issued for you
| (the `aud` claim)
|
| Most libraries I have interacted with check the first two, but
| not the last two.
| progre wrote:
| I didn't know the token format wasn't specified, thanks for
| the clarification! I've only ever come across JWT:s.
| cratermoon wrote:
| > the token is signed according to the algo and the key that
| you expect
|
| Important point! Especially with JWT. It must be the
| algorithm you _EXPECT_ , not the algorithm in the token.
| Someone flubbed up and made the "none" algorithm _mandatory_
| for spec-compliant implementations. Unfortunately, that can
| result in _any_ JWT being treated as valid.
|
| It's a chicken-and-egg problem that the designers missed: you
| can't trust the token until you've validated it, but you'd
| have to believe the value of the algo field _before_ you 've
| validated it in order to check the signature.
|
| There are libraries that will see "none" in the algo field
| and treat that as "this token doesn't have a signature that
| needs to be validated, so it's good".
| UnlockedSecrets wrote:
| It can be authenticated as coming from a trusted party but
| cannot be authenticated against a user password because the
| system has no way of knowing any secrets provided by the user.
| progre wrote:
| Well, that's kind of the point right? Keeping user secrets
| out of the trusting system.
___________________________________________________________________
(page generated 2021-03-27 23:00 UTC)