Skip to content
This repository has been archived by the owner on Mar 29, 2019. It is now read-only.

Failing to verify the application id? #20

Open
iagox86 opened this issue Oct 20, 2017 · 1 comment
Open

Failing to verify the application id? #20

iagox86 opened this issue Oct 20, 2017 · 1 comment

Comments

@iagox86
Copy link

iagox86 commented Oct 20, 2017

Hey, I was playing around with this library, and I noticed that I could get a token issued under one client id, and validate it with another. It's possible I'm missing something, but I think this may be vulnerable to a confused deputy problem.

For example, I can take my oauth app from Google:

926872579832-ruurs5s2cirehpavk7141n2tqqjj5el5.apps.googleusercontent.com

Generate a token with it using this link, in a browser (I'm doing this from Ember, which doesn't matter):

https://accounts.google.com/o/oauth2/v2/auth?response_type=token&client_id=926872579832-ruurs5s2cirehpavk7141n2tqqjj5el5.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Ftorii%2Fredirect.html&state=z7D36Js0tlu8b6Xx&scope=email

Which gives me the token:

ya<censored>8e

If I use tokeninfo, it validates to that app id:

$ curl 'https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=ya<censored>8e'

{
"azp": "926872579832-ruurs5s2cirehpavk7141n2tqqjj5el5.apps.googleusercontent.com",
"aud": "926872579832-ruurs5s2cirehpavk7141n2tqqjj5el5.apps.googleusercontent.com",
"sub": "",
"scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me",
"exp": "1508539316",
"expires_in": "3522",
"email": "[email protected]",
"email_verified": "true",
"access_type": "online"
}

But when I validate it in passport-google-token configured as such (note that clientID is different, as is clientSecret):

  passport.use(
    new GoogleTokenStrategy({
      clientID: '926872579832-dij365g8vl2j7ntsq8ib09toegel1lp1.apps.googleusercontent.com',
      clientSecret: '<censored>',
    },
    function(accessToken, refreshToken, profile, done) {
      console.log(accessToken);
      console.log(profile);

      return done(null, {});
    })
  );

It successfully validates the token (I'm censoring some fields):

{ provider: 'google',
  id: '<id>',
  displayName: '',
  name: { familyName: '', givenName: '' },
  emails: [ { value: '<email>' } ],
  _raw: '{\n "id": "<id>",\n "email": "<email>",\n "verified_email": true,\n "name": "",\n "given_name": "",\n "family_name": "",\n "picture": "https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg",\n "hd": "<email>"\n}\n',
  _json: 
   { id: '<id>',
     email: '<email>',
     verified_email: true,
     name: '',
     given_name: '',
     family_name: '',
     picture: 'https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg',
     hd: '<domain>' } }

I'm pretty sure that's incorrect behaviour. From Google's docs, it says:

Important: Before using the token, you need to verify that this field's value exactly matches your Client ID in the Google API Console. This verification ensures that your application is not vulnerable to the confused deputy problem.

I'm pretty sure that's not happening.

@iagox86
Copy link
Author

iagox86 commented Oct 20, 2017

I noticed looking at the code that this uses userinfo and not tokeninfo, so it might be that this library isn't designed to validate the token, just to use it. Let me know if that's the case. :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant