OAuth is a popular authorization schema used by many iOS and Android apps to delegate user authentication and authorization to a known third-party entity such as Google, Facebook or LinkedIn. This includes apps that enterprises develop to connect to G Suite, or other social media apps accessed by employees on a daily basis. When installing such apps on their mobile devices, users see a consent screen like the below asking for access to other Google services:
Users often grant app access to their Gmail account or Google Drive without thinking about what this access allows app developers to do. There are several functionalities app developers can tap into when they get access, even when the app is not in use. This may come as a surprise to mobile users because they are often not aware of the amount of data an app can access both online and offline, nor of the consequences of sharing data with the app. Depending on the requested permissions and access type, an app can essentially keep a user authenticated forever and continue accessing personal data from their Gmail, Google Drive, Google Calendar, or other services containing sensitive information.
OAuth and Google Authorization
To begin using the Google Authorization service, an app developer first needs to register and obtain OAuth client credentials from the Google Developer’s Console. Unlike web applications where the client secret can be securely stored on the server and be used in combination with a client ID for authentication, there is no secure way for mobile apps to statically store the client secret. As a result, apps commonly authenticate to Google’s authorization server using only their public client ID. The client ID is used to exchange an authorization code for an access token.
App developers also need to define scopes (permissions) they require access to in the OAuth consent screen:
Scopes can later be requested in both online and offline mode when redirecting the user to the authorization page. If scopes were requested in offline-mode, then the app can request access tokens at any time, even when the user is offline. Figure 1 above shows Microsoft Outlook’s consent screen requesting full access to Gmail, Google Drive, and Google Calendar in offline mode. As can be seen in the picture, from the consent screen itself, there is no way for the user to know if the app is requesting offline or online access.
Here is the request made to redirect the user to the Google consent screen (figure1) with the list of scopes that the app has requested. The user can then select “allow” or “deny” on the consent screen.
If the end user allowed access, an authorization code is then returned to the app. The app can exchange this authorization code for an access token allowing it to read a user’s protected resources through Google APIs:
In mobile apps with public client IDs, anyone who can intercept the authorization code can exchange it for an access token. OAuth providers such as Google secure this code exchange process by adding a PKCE (Proof Key for Code Exchange) mechanism. With PKCE the app generates a high-entropy random string called “code_verifier” and sends its encoded value (“code_challenge”) to the server in the first authorization request. When exchanging the authorization code for an access token, the original value of Code_verifier is sent to the server and is compared with the previously received encoded value. This process is not as secure as the passing of client secrets in web applications, but it makes forging code exchange requests harder in mobile apps where statically-stored client secrets can be stolen more easily.
In response to the above code exchange request (Figure 3), the app will receive an access token, and an optional refresh token, if offline access type has been requested in the first authorization request (Figure 2). In our example, the app will receive both:
Access tokens have a short shelf life and generally expire after an hour. In order to maintain continuous access, a refresh token is used to renew access tokens. As mentioned earlier, refresh tokens are only provided to the app if offline access type has been requested. This access type is required for apps that need access to Google APIs when a user is not present, e.g. for running scheduled tasks. However, for security reasons, offline requests to sensitive scopes must be avoided or be limited to the exact required functionality. Full access to Gmail and Google Drive are the two most restricted scopes apps can ask for, and developers should avoid and replace them with other, less-permissive scopes, as advised in Google Developers Documentation.
Requests to Sensitive Scopes Are Not Always Needed
Our research shows that requests to restricted permissions, especially in offline mode, are not necessary for the main functionality of many apps, and in most cases can be replaced with less sensitive scopes (e.g. gmail.readonly, gmail.compose, gmail.modify, etc).
To demonstrate how the refresh token process happens in offline mode, we modified the Approov Books App, part of Approov’s collection of open-source code examples which implement OAuth2 by using the AppAuth SDK. AppAuth is a popular SDK used by Android and iOS apps to communicate with OAuth 2.0 and OpenID Connect providers. The AppAuth library “follows the best practices set out in RFC 8252 - OAuth 2.0 for Native Apps,” and also “supports the PKCE extension to OAuth which was created to secure authorization codes in public clients when custom URI scheme redirects are used.”
Our demo app requests full access to Gmail, Google Drive, and Google Calendar in offline mode. The below are descriptions of what each of the scopes provides access to.
“Full access to the account, including permanent deletion of threads and messages. This scope should only be requested if your application needs to immediately and permanently delete threads and messages, bypassing Trash; all other actions can be performed with less permissive scopes.”
“Full, permissive scope to access all of a user's files, excluding the Application Data folder. Request this scope only when it is strictly necessary."
“See, edit, share, and permanently delete all the calendars a user can access using his Google Calendar.”
Refresh tokens have a long shelf life and are subject to strict storage requirements to ensure they are not leaked.
See the video below that shows how easily the app can get new access tokens outside the app, using only a refresh token and its public client ID.
To prevent token leakages (which is more likely to happen in apps) some apps save tokens outside the app in a server-side database. This added layer of protection might secure tokens from attacks, but it gives more authority to app developers to keep and/or misuse tokens.
Despite mobile users’ common assumptions, neither signing out from the app or Google, nor app removal will cause the refresh token to expire unless the app or the user revokes access. To prevent any misuse or exposure of a user’s sensitive data, it is important that apps revoke the given access when the user uninstalls the app. Surprisingly, among the 1800 apps we analyzed with offline scopes to Google APIs, none of them revoke access during the uninstall process. This includes known email clients such as Microsoft Outlook email & calendar app (Android and iOS).
The following shows examples of apps in different categories which request sensitive scopes in offline mode.
|Boxer - Workspace ONE||Business/Finance, Email Client||Gmail, Calendar|
|Newton Mail - Email App||Business/Finance, Email Client||Gmail|
|Microsoft Outlook||Business/Finance, Email Client||Gmail, Drive, Calendar|
|Flow Mail - tames mobile inbox||Business/Finance, Email Client||Gmail|
|Email - email mailbox||Email Client||Gmail|
|Email TypeApp - Mail App||Email Client||Gmail|
|Blue Mail - Email & Calendar App - Mailbox||Email Client||Gmail, Calendar|
|Monster Job Search||Business/Finance, Job Search||Gmail, Drive|
|Slice - Package Tracker||Shopping/Receipt Tracker||Gmail|
|Paribus: Money Back Shopping||Shopping/Receipt Tracker||Gmail|
|Postagram: Photo Postcards||Social Networking/Hobbies & Interest||Gmail|
|Meme Soundboard 2019 - DANK, MLG, Ringtone & More||Social Networking/Hobbies & Interest||Drive|
|Adobe Sign||Business/Finance, Technology||Drive|
|Home Security Camera WardenCam - reuse old phones||Home Surveillance||Drive. Files|
|Smart Home Surveillance Picket - reuse old phones||Home Surveillance||Drive. Files|
Additionally, the figure below shows the distribution of apps requesting full access to Gmail, Google Drive, and/or Google Calendar in iOS and Android:
What’s at Risk?
When users give an app access to their Google services, they are essentially allowing the app’s developer to make a copy of their data and store it on the developer’s servers. Google holds no responsibility for the security of data stored in third party servers. This means that, while Google may be doing its best to secure users’ emails, if they have given an app access to their Gmail, that app can store their emails in a non-secure way in the app server, putting the data at risk of leakage.
Persistent access to user data augments the risk. Imagine an app with access to your Google Drive. You uninstall the app, and assume the app developer doesn’t have access to your files anymore. However, unless you or the developer revoke the authorization, that app can still access new files you add to your Drive.
Conclusion and Recommendations
Despite the use of OAuth security techniques such as PKCE or state-based parameters for preventing cross-site request forgery attacks, authorization misuse prevention has been left to developers, usually as a “recommended” but still “optional” choice. Unfortunately, this can open the door to malware, including ransomware where unauthorized access to files can occur outside the app while the user is offline. This also could lead to exposure of sensitive corporate data including emails, Google Drive files, and calendar information.
In this article, we looked at Google as the major OAuth provider. Facebook and LinkedIn are two other players which are exposed to OAuth security concerns; the concerns may be smaller compared to Google, but can still be significant for certain organizations. Access tokens in Facebook and LinkedIn by default expire after 90 and 60 days respectively, leaving a smaller window for exploitation. However, Facebook has a set of permissions that never expire. For instance, Publish_pages and Manage_pages, can give an app unlimited access to publish to the user’s pages.
Based on secure coding best practices, apps should:
- Avoid requesting sensitive permissions specially in offline mode. Sensitive permissions should be replaced with less permissive scopes that the app requires to perform its main functionalities while the user is offline.
- Ask for offline access only if it is necessary for the app’s main functionalities.
- Follow an incremental authorization practice, i.e. request for the basic scopes and then ask for additional scopes when the user wants to perform an action that requires additional scopes.
- Programmatically revoke the given access whenever the user uninstalls the app.
SEP Mobile Protection Against OAuth Authorization Misuse
Symantec’s mobile threat defense solution, Symantec Endpoint Protection Mobile (SEP Mobile), enables organizations to set an “unwanted apps” policy through which they can mitigate the risk from apps asking for excessive permissions using the OAuth protocol. The unwanted apps policy allows admins to set the conditions for which an app is determined as risky/unwanted. Admins can select OAuth misuse and other vulnerabilities from a list of app behavior conditions.
Apps that meet the condition of “requesting excessive Google service permissions using OAuth” are classified as unwanted and their installation can automatically be prevented, or they can be removed from the device if they are already installed, according to the organization’s policy. For example, SEP Mobile detected an app (below) in our customer install base that requested excessive Google scopes using the OAuth protocol. The app was marked as “unwanted” with a classification of “OAuth misuse”, and the admin was alerted to the incident. The app was prevented from being installed according to the organization’s policy.
The OAuth misuse condition is included in SEP Mobile’s recommended unwanted app rules and it is, by default, a part of every new SEP Mobile environment.