[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)