Skip to content

Instantly share code, notes, and snippets.

@nksmkj7
Forked from mziwisky/Oauth2.md
Created November 24, 2022 11:13
Show Gist options
  • Select an option

  • Save nksmkj7/0ecd45463ad3bcf8eebf9dea9f9f323e to your computer and use it in GitHub Desktop.

Select an option

Save nksmkj7/0ecd45463ad3bcf8eebf9dea9f9f323e to your computer and use it in GitHub Desktop.

Revisions

  1. @mziwisky mziwisky revised this gist Oct 11, 2022. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions Oauth2.md
    Original file line number Diff line number Diff line change
    @@ -37,8 +37,6 @@ Gmail stores server-side: PrettyMail stores server-side: Note: client_
    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the `redirect_uri` it got in the first place, passing along that code: `prettymail.com/oauth_response?code=big_long_thing`

    *Question:* why not pass the AuthToken itself along at that step? Answer: so Gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests Gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its `client_id`, which isn’t “secret” (i.e. an attacker could guess it). So Gmail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.

    *Other Question:* rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.

    6. PrettyMail takes the code and directly (i.e., not via a REDIRECT in the user’s browser, but via a server-to-server request) queries Gmail with both code and shared secret, to prove its identity: `GET gmail.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=big_long_thing`

  2. @mziwisky mziwisky revised this gist Feb 3, 2021. 1 changed file with 14 additions and 10 deletions.
    24 changes: 14 additions & 10 deletions Oauth2.md
    Original file line number Diff line number Diff line change
    @@ -23,23 +23,27 @@ Gmail stores server-side: PrettyMail stores server-side: Note: client_

    1. I visit PrettyMail and click “Login thru GMail”

    2. PrettyMail responds REDIRECT gmail.com/oauth2/auth?client_id=ABC&redirect_uri=prettymail.com/oauth_response
    2. PrettyMail responds `REDIRECT gmail.com/oauth2/auth?client_id=ABC&redirect_uri=prettymail.com/oauth_response`
    -- note: also common to include ‘scopes’ in query -- i.e., the scope of the information that PrettyMail is asking to access

    3. gmail makes a session in which it stores provider (PrettyMail, based on client_id -- if client_id doesn’t refer to an authorized oauth_client, render an error) and redirect_uri and then responds:
    3. Gmail makes a session in which it stores provider (PrettyMail, based on `client_id` -- if `client_id` doesn’t refer to an authorized oauth_client, render an error) and `redirect_uri` and then responds:

    a. REDIRECT gmail.com/login (for a login form) if the user isn’t logged in, otherwise
    a. `REDIRECT gmail.com/login` (for a login form) if the user isn’t logged in, otherwise

    b. REDIRECT directly to step (4)
    b. `REDIRECT` directly to step (4)

    4. gmail shows a page saying “PrettyMail (got that from the aforementioned session) wants to access this, that, and the other thing (again, ‘scope’ of access was stored in the session) about your Gmail account. Do you authorize?” You click “yup” and gmail:
    4. Gmail shows a page saying “PrettyMail (got that from the aforementioned session) wants to access this, that, and the other thing (again, ‘scope’ of access was stored in the session) about your Gmail account. Do you authorize?” You click “yup” and Gmail:

    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the redirect_uri it got in the first place, passing along that code: prettymail.com/oauth_response?code=big_long_thing
    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the `redirect_uri` it got in the first place, passing along that code: `prettymail.com/oauth_response?code=big_long_thing`

    Question: why not pass the AuthToken itself along at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.
    *Question:* why not pass the AuthToken itself along at that step? Answer: so Gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests Gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its `client_id`, which isn’t “secret” (i.e. an attacker could guess it). So Gmail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.

    Other Question: rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.
    *Other Question:* rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.

    6. PrettyMail takes the code and directly (i.e., not via a REDIRECT in the user’s browser, but via a server-to-server request) queries GMail with both code and shared secret, to prove its identity: GET gmail.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=big_long_thing
    6. PrettyMail takes the code and directly (i.e., not via a REDIRECT in the user’s browser, but via a server-to-server request) queries Gmail with both code and shared secret, to prove its identity: `GET gmail.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=big_long_thing`

    7. gmail verifies and then invalidates the code, and responds with an AccessToken, which PrettyMail can then use (until it expires) to make API requests on the user’s behalf (i.e., to get info about the user, and possibly to perform actions on behalf of the user, if that was in the agreed-upon ‘scope’ of the arrangement)
    7. Gmail verifies and then invalidates the code, and responds with an AccessToken, which PrettyMail can then use (until it expires) to make API requests on the user’s behalf (i.e., to get info about the user, and possibly to perform actions on behalf of the user, if that was in the agreed-upon ‘scope’ of the arrangement)

    ## Security Addendum: the `state` param

    This gist has gotten more attention than I thought it would. Not an avalanche by any means, but I still feel I should point out an important omission from the original -- there's an XSRF vulnerability in Oauth2 that is easily closed by use of a `state` param. This param enables the 3rd party app (PrettyMail) to trust that the request from step (5) above (to the `redirect_uri`) is legitimately from the user. Here's a [StackOverflow](https://stackoverflow.com/questions/26132066/what-is-the-purpose-of-the-state-parameter-in-oauth-authorization-request) about it, and here's a [blog post](http://homakov.blogspot.com/2012/07/saferweb-most-common-oauth2.html) that goes into greater detail. In the name of simplicity (and laziness), I have not modified the above explanation to include this param. *You*, however, should *not* be lazy in your implementation -- you should include it.
  3. @mziwisky mziwisky revised this gist Apr 8, 2014. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions Oauth2.md
    Original file line number Diff line number Diff line change
    @@ -36,9 +36,9 @@ Gmail stores server-side: PrettyMail stores server-side: Note: client_

    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the ‘redirect_uri’ it got in the first place, passing along that code: prettymail.com/oauth_response?code=big_long_thing

    Question: why not pass the AuthToken itself along at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.

    Other Question: rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.
    Question: why not pass the AuthToken itself along at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.
    Other Question: rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.

    6. PrettyMail takes the code and directly (i.e., not via a REDIRECT in the user’s browser, but via a server-to-server request) queries GMail with both code and shared secret, to prove its identity: GET gmail.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=big_long_thing

  4. @mziwisky mziwisky revised this gist Apr 8, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions Oauth2.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    I’m a web app that wants to allow other web apps access to my users’ information, but I want to ensure that the user says it’s ok.

    ## The Solution
    I can’t trust the other web apps, so I must interact with my users directly. I’ll let them know that the other app is trying to get their info, and ask whether they want to grant that permission. Oauth defines a way to initiate that permission verification from the other app’s site so that the user experience is smooth.
    I can’t trust the other web apps, so I must interact with my users directly. I’ll let them know that the other app is trying to get their info, and ask whether they want to grant that permission. Oauth defines a way to initiate that permission verification from the other app’s site so that the user experience is smooth. If the user grants permission, I issue an AuthToken to the other app which it can use to make requests for that user's info.

    ### Note on encryption
    Oauth2 has nothing to do with encryption -- it relies upon SSL to keep things (like the client app’s shared_secret) secure.
    @@ -36,7 +36,7 @@ Gmail stores server-side: PrettyMail stores server-side: Note: client_

    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the ‘redirect_uri’ it got in the first place, passing along that code: prettymail.com/oauth_response?code=big_long_thing

    Question: why not pass the token along directly at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.
    Question: why not pass the AuthToken itself along at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.

    Other Question: rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.

  5. @mziwisky mziwisky created this gist Apr 8, 2014.
    45 changes: 45 additions & 0 deletions Oauth2.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    # OAUTH2

    ## The Problem
    I’m a web app that wants to allow other web apps access to my users’ information, but I want to ensure that the user says it’s ok.

    ## The Solution
    I can’t trust the other web apps, so I must interact with my users directly. I’ll let them know that the other app is trying to get their info, and ask whether they want to grant that permission. Oauth defines a way to initiate that permission verification from the other app’s site so that the user experience is smooth.

    ### Note on encryption
    Oauth2 has nothing to do with encryption -- it relies upon SSL to keep things (like the client app’s shared_secret) secure.

    ## Example Scenario:
    Gmail wants to allow some 3rd party app, PrettyMail, to do stuff with its users’ information.

    ```
    Gmail stores server-side: PrettyMail stores server-side: Note: client_id tracks the user of the
    oauth_clients: [ client_id: ABC oauth privileges, i.e., PrettyMail or
    pretty_mail: { shared_secret: XYZ other web app -- not the end-users
    client_id: ABC
    shared_secret: XYZ
    }, ...]
    ```

    1. I visit PrettyMail and click “Login thru GMail”

    2. PrettyMail responds REDIRECT gmail.com/oauth2/auth?client_id=ABC&redirect_uri=prettymail.com/oauth_response
    -- note: also common to include ‘scopes’ in query -- i.e., the scope of the information that PrettyMail is asking to access

    3. gmail makes a session in which it stores provider (PrettyMail, based on client_id -- if client_id doesn’t refer to an authorized oauth_client, render an error) and redirect_uri and then responds:

    a. REDIRECT gmail.com/login (for a login form) if the user isn’t logged in, otherwise

    b. REDIRECT directly to step (4)

    4. gmail shows a page saying “PrettyMail (got that from the aforementioned session) wants to access this, that, and the other thing (again, ‘scope’ of access was stored in the session) about your Gmail account. Do you authorize?” You click “yup” and gmail:

    5. generates a one-time-use code that it associates with PrettyMail and the specified user and the requested scope (so it persists it until the next step) and REDIRECTs to the ‘redirect_uri’ it got in the first place, passing along that code: prettymail.com/oauth_response?code=big_long_thing

    Question: why not pass the token along directly at that step? Answer: so gmail can ensure that PrettyMail is indeed the requester of the access -- so far, all the requests gmail has gotten have come directly from the user, and the only information that identified PrettyMail was its client_id, which isn’t “secret” (i.e. an attacker could guess it). So GMail so far is confident that the user is ok with everything, but isn’t yet convinced that PrettyMail is really going to be the one using the Token. That’s where the next request comes in, in which PrettyMail identifies itself by including the shared secret.

    Other Question: rather than redirecting to a URL containing the code as a param, why not just send the final AccessToken to PrettyMail right then and there? Answer: (i’m guessing) the redirect basically “gives control” of the browser back to PrettyMail, so they can handle the request any way they want.

    6. PrettyMail takes the code and directly (i.e., not via a REDIRECT in the user’s browser, but via a server-to-server request) queries GMail with both code and shared secret, to prove its identity: GET gmail.com/oauth2/token?client_id=ABC&client_secret=XYZ&code=big_long_thing

    7. gmail verifies and then invalidates the code, and responds with an AccessToken, which PrettyMail can then use (until it expires) to make API requests on the user’s behalf (i.e., to get info about the user, and possibly to perform actions on behalf of the user, if that was in the agreed-upon ‘scope’ of the arrangement)