I was looking into how the Google Play library actually obtains OAuth tokens on behalf of apps, as the actual nuts and bolts remain undocumented.

Its implementation offers some interesting insights into how Google handles issues that crop up up when using OAuth in an Android app. The rest of this post presumes you know a bit about Android, OAuth as well as how to use the Google Play Services library to obtain access tokens. Sorry if all this is down in the weeds, but that's where the fun bits are!

To get a disclaimer out of the way. These are just my observations after poking at various dex files and network traffic and I've undoubtedly missed many things; but I do hope to show you the broad outline of how it works.

There are three points of interest.

  1. Critical code runs only within a Google signed app (eg: the com.google.android.gms/.auth.GetToken service.)
  2. This service approves apps locally, and obtains access tokens using a locally stored master token. It effectively replaces the traditional web-based OAuth approval flow.
  3. Third-party apps are identified by their signature and package name, rather than an application-key/application-secret.

The green areas run "trusted" code. Your app uses the Google Play Services client library; but the library itself doesn't run critical code. It instead forwards calls to services and activities running within a separately installed app ("Google Play Services".)

Here are some interesting bits of the manifest file for com.google.android.gms (the "Google Play services" app) so you get a feel for how it is set up.

<manifest
  android:sharedUserId="com.google.uid.shared"
  package="com.google.android.gms"
  ...>
  <service
    android:name=".auth.GetToken"
    android:exported="true"
    android:process="com.google.process.gapps"/>

  <activity
    android:name=".auth.login.LoginActivity"
    android:exported="true"
    android:process="com.google.android.gms.ui"
    .../>

As an app writer, you typically call GoogleAuthUtil.getToken() from your application. The Play Services library first verifies that the required Google apps (com.android.vending and com.google.android.gms) are installed, and also that they have an acceptable version and signature. The acceptable version numbers and signature are embedded directly within the library. Your requested OAuth scope is passed to the service, and now we're running inside the trusted Play Services app.

Things start to get interesting within the get-token service.

This service first retrieves the app package name and signature of the caller. This pair (caller_package_name,caller_signature) is used to identify the caller. This mutual identification/verification by the service and the calling library takes place right at the outset; and presumably makes it more difficult for either the caller or a rogue "Play Service" to spoof their identity to the other.

The service directly manages app approval, shows dialogs to the user as needed, and creates access tokens for requested scopes. In other words, it performs the app-approval that would otherwise typically be done by the web-site.

This approach does have some advantages. By using a locally running service in a trusted Google app, Google can take advantage of some of the security features within Android.

For example, by using the package signature to identify your application, it eliminates the need to embed application ids and secrets in your apk (which can often be extracted out of a downloaded application; allowing the bad guys to sign requests as if they came from your app.) Package signatures are much harder to spoof - you'll need the private signing key which is (hopefully!) never revealed; so this is a better way to identify an app.

Further, all the access approval UI and token acquisition logic is sandboxed inside the play app rather than being left to the app-writer. Presumably, this reduces the "attack-surface", and also allows bugs to be addressed quickly by updating this single app.

You might now be imagining the flip side of such a powerful Android service, and you'd be right. This service has to be secure and correctly alert the user during approval; for once provisioned, it is capable of creating access tokens on behalf of any app, and with any scope.

The get-token service does all this using what I call a master token that it obtains from an undocumented authentication endpoint at https://android.clients.google.com/auth. Here's how it works.

When you first add an account to the device (say during device setup) the service posts your password, which is additionally encrypted with, I believe, a public key whose private counterpart is available to the web endpoint.

POST https://android.clients.google.com/auth
Parameters
----------
accountType:      HOSTED_OR_GOOGLE
Email:            xxx@gmail.com
has_permission:   1
add_account:      1
EncryptedPasswd:  <some base64 encoding>
service:          ac2dm
source:           android
androidId:        <deviceid>
device_country:   us
operatorCountry:  us
lang:             en
sdk_version:      17

A successful login returns back a bunch of user information and tokens, one per line.

SID=...
LSID=...
Auth=...
services=hist,mail,lh2,talk,oz
Email=...
Token=1/zMASTERTOKEN
GooglePlusUpgrade=1
PicasaUser=...
RopText= 
RopRevision=1
firstName=...
lastName=...

Note the Token field - this is the one master token to rule them all.

The master token is stored on the device using the AccountManager. You should be aware that in most device configurations, AccountManager stores this token in an unencrypted sqlite database (accounts.db - usually somewhere under /data/system.) Protection is primarily through the basic linux file-system access controls - the directories are accessible only to system processes.

My understanding of the Android Security Team's position is that anything else is fundamentally security theatre. Encrypting the data or the filesystem is a tricky subject and solutions are often contentious. At any rate; it means rooted devices (or devices that can be rooted through an OS/driver weakness) are at risk of exposing the master token - so be aware.

Next, a set of core google services request OAuth tokens for their scopes. This also reveals how the get-token service generates access tokens using the master token. Here for example, is how it creates a token for one of the scopes requested by the market app.

POST https://android.clients.google.com/auth

Parameters
----------
accountType:      HOSTED_OR_GOOGLE
Email:            ...
has_permission:   1
Token:            1/zMASTERTOKEN
service:          sierra
source:           android
androidId:        <deviceid>
app:              com.android.vending
client_sig:       38918a453d07199354f8b19af05ec6562ced5788
device_country:   us
operatorCountry:  us
lang:             en
sdk_version:      17

and sure enough - it gets back:

SID=...
LSID=...
Auth=<auth_token>
issueAdvice=auto
services=hist,mail,lh2,talk,oz

Indeed, all it takes is to add the has_permission=1 flag to a request containing the master token, and down comes an access token for the desired scope. I also believe this permission is automatically added if the service notices that the requestor signature is the same as the google app signature; which is in fact the SHA value you see above.

What happens when you request a token from your own app via GoogleUtils.getToken() for the userinfo.profile scope?

POST https://android.clients.google.com/auth
Headers
-------
device:          <deviceid>
app:             <app-package-name>

Parameters
----------
device_country:                us
operatorCountry:               us
lang:                          en_US
sdk_version:                   17
google_play_services_version:  4132532
accountType:                   HOSTED_OR_GOOGLE
Email:                         <email>
source:                        android
androidId:                     <device_id>
app:                           <app-package-name>
client_sig:                    <app-sha-signature>
service:                       oauth2:https://www.googleapis.com/auth/userinfo.profile
Token:                         1/zMASTERTOKEN

Note the absence of the has_permission=1 flag, and that the client_sig is now the signature of the calling app.

The response is:

issueAdvice=consent
Permission=View+basic+information+about+your+account
ScopeConsentDetails=%0AView+your+name%2C+public+profile+URL%2C+and+photo%0AView+your+gender%0AView+your+country%2C+la
nguage%2C+and+timezone%0A
ConsentDataBase64=...

The user-interface is controlled by the issueAdvice flag in the response. Automatically approved apps get the issueAdvice=auto flag and an access token. issueAdvice=consent causes the service to return an Intent that if launched, shows a suitable consent dialog. (The Play Services client library bundles this Intent into a UserRecoverableAuthException.)

What happens when you approve a consent dialog? Nothing much - the service merely adds the has_permission=1 flag to a similar request and gets back an access token. It really can create access tokens for any and all scopes.

By the way - this also indicates how the verified app call mechanism likely works. If you specify a audience:server:client_id scope, the token service passes it as usual with the (caller_package,caller_signature) pair to the server. The server checks if this matches the information you separately registered for that app, and returns a JSON Web Token asserting this fact.

Naturally, all this assumes the basic Android system, as well as the "trusted" Play Services app can securely identify the calling package; and that nobody other than the trusted app has access to the master token.

Given those assumptions, it's a nice technique. The Play Services App contains an omnipotent "local-oauth-service"; playing the role of the web-based approval flow but with an Android flavor. Third-party apps are identified directly by their app signature, removing the need to embed app secrets within the apk file.

Most users need (and should) enter their google password only when setting up their device. Apps no longer use the inherently insecure Webview approach to trigger the approval flow; nor do they need to use the awkward and tedious flow via a browser Intent. The app never sees anything other than the access token itself. Critical code runs only in the Play Services app, so bugs can be fixed by just updating one app.

Downsides?

Be aware there's a master token stored on your Android device which has the latent ability to grant access to services you might not even be accessing from it. If that token is ever exposed, you should assume that all data associated with the account is up for grabs. Use the Android Device Manager to reduce the window of opportunity if your device is stolen, or manage this master token from your security settings. Or, use a low-value account just for your android devices; and keep critical documents in a separate account.

23 comments:

Thanks a lot.

August 5, 2015 at 3:34 PM  

It is safe to say that you are looking for the Largest Android Tablet in 2020? The correct method to buy tablets is through the online sites. There are various sites that include enormous measure of biggest screen tablets.

May 11, 2020 at 4:34 AM  

Next time I read a blog, Hopefully it does not fail me just as much as this one. After all, I know it was my choice to read, however I actually believed you would probably have something useful to talk about. All I hear is a bunch of complaining about something you could possibly fix if you weren't too busy searching for attention.pres control san antonio coronavirus

July 18, 2020 at 5:05 AM  

Hi there! This blog post could not be written much better! Going through this post reminds me of my previous roommate! He constantly kept preaching about this. I am going to forward this article to him. Fairly certain he's going to have a great read. Thanks for sharing!
Gutter repair

August 3, 2020 at 3:08 AM  

I was more than happy to uncover this great site. I need to to thank you for your time due to this fantastic read!! I definitely enjoyed every bit of it and I have you bookmarked to see new information on your blog.
E-Commerce in Lahore

September 23, 2020 at 5:30 AM  

I'd like to thank you for the efforts you've put in writing this website. I really hope to see the same high-grade blog posts from you later on as well. In truth, your creative writing abilities has motivated me to get my very own site now ;)
I was pretty pleased to uncover this web site. I wanted to thank you for ones time due to this fantastic read!! I definitely liked every part of it and i also have you saved as a favorite to check out new things in your web site.
Europe Brand

October 5, 2020 at 6:19 AM  

Eco living life team is passionate about making it easier for you to shop online. We care about your time so we try our best to make your shopping experience pleasant, seamless and hassle-free.

October 17, 2020 at 4:01 PM  

Aw, this was a very nice post. Taking the time and actual effort to produce a superb article… but what can I say… I procrastinate a whole lot and never manage to get anything done.

At BrokeScholar we work around the clock to update this page with active promo codes, coupons and discounts for Total Wine . Our editors monitor newsletters, social media posts, deal forums, and third party sellers to find the best Total Wine deals. For students, we also track totalwine student discounts for exclusive savings. We've done the research so you don't have to. Bookmark this page and never miss a Total Wine promotion again.

November 10, 2020 at 6:40 AM  

Stretch your dollar even further at harbor freight coupons with our 25% off coupons. These coupons will help you save 20% (or more!) on qualifying items throughout the store. We also have discounts just for members of our Inside Track Club.

November 19, 2020 at 9:49 AM  

This online journal site is really cool! How was it made !

Kilts for Sale

November 24, 2020 at 10:34 PM  

Goodness, this is truly intriguing perusing. I am happy I discovered this and got the chance to peruse it. Awesome employment on this substance. I like it.

Utility Kilts

November 27, 2020 at 9:21 PM  

Goodness, this is truly intriguing perusing. I am happy I discovered this and got the chance to peruse it. Awesome employment on this substance. I like it.

How To Build Hybrid Kilt - Complete Helping Guide

November 29, 2020 at 9:34 PM  

i was simply perusing along and happened upon your online journal. simply needed to say great website and this article truly helped me.

Smart Automation Solutions

November 30, 2020 at 1:56 AM  

Howdy! Pleasant post! It would be ideal if you let us know when I will see a postliminary!
Graphic designing services in Lahore

December 18, 2020 at 5:46 AM  


Professionelles Übersetzungsbüro ✓ Übersetzungen ✓ Dolmetschen ✓ mehr als 35 Jahre Erfahrung ✓ alle Sprachen ✓ Qualitätsstandard ISO 17100 ✓ Rechtssichere Übersetzung ✓ Juristische Fachübersetzung ✓ Übersetzungsbüro ✓ Übersetzungsdienst ✓Übersetzungsagentur ✓Übersetzungsservice ✓ Übersetzungen ✓ beglaubigte ✓ Übersetzung, Übersetzen ✓individuelle Beratung.✓✓ Alle Sprachen. Alle Fachrichtungen,✓ 35 Jahre Erfahrung ✓ Express Übersetzungsbüro ✓ juristische und technische Übersetzung ✓ Profi Fachübersetzungen ✓ Deutsch Englisch
Übersetzung für Versicherung Insurance Französich


January 11, 2021 at 10:42 AM  

On this website, You’ll get over 200+ real working dark web links and If you’re a regular dark web user so you can start using these dark web links and If you’re a new user or If you don’t know anything about the dark web So you can read the content below and you’ll understand everything about the dark web.

February 9, 2021 at 4:43 AM  

I was more than happy to uncover this great site. I need to thank you for your time due to this fantastic read!!
I definitely enjoyed every bit of it and I have you bookmarked to see new information on your blog.
Classified Ads WordPress Theme

March 12, 2021 at 4:41 AM  

I was more than happy to uncover this great site. I need to thank you for your time due to this fantastic read!!
I definitely enjoyed every bit of it and I have you bookmarked to see new information on your blog.
Freelance Marketplace WordPress Theme

March 15, 2021 at 4:03 AM  

I was more than happy to uncover this great site. I need to thank you for your time due to this fantastic read!!
I definitely enjoyed every bit of it and I have you bookmarked to see new information on your blog.
Freelance Marketplace WordPress Theme

March 16, 2021 at 3:53 AM  

رقم نقل عفش
نقل عفش رخيص – نقل عفش بالكويت – مصطفى 99003870 – نقل عفش حولي – نقل اثاث ايكيا – نقل عفش السالمية – شركة نقل اثاث – نقل عفش الاحمدي – نقل عفش

March 28, 2021 at 1:54 PM  

digital marketing agency london
Moving on to the best and most suitable campaign(s) for your business after spotting your position in the market along with your competitors. Creation of strategies as well as optimization process setup is an essential part of this phase including targets which could be ROAS, ROI or CPA.

April 12, 2021 at 9:00 AM  

I truly like your composition style, awesome data, thankyou for posting.

freetress suzie

April 20, 2021 at 1:20 AM  

Thanks for uploading this article. Techno mobile is best mobile with best specifications. Now you can get new mobiles update with Vivo y20 price in Bangladesh

May 9, 2021 at 3:52 AM  

Older Post Home

Labels