Reminder: oauth tokens and application passwords give attackers persistence (part I)

The recent dispute over whether Twitter itself experienced a breach or merely oauth tokens were compromised from a third-party website serves as a useful reminder about the risks of “alternative account access” credentials. That phrase is intended to cover the different ways of accessing user data held by a cloud provider without going through the standard authentication process such as typing a username and password.

These side-channels present two problems:

  • They can become the primary avenue for account hijacking
  • More subtly they can function as backdoor to persist access, after the attacker has obtained unauthorized access to the account in some other way

Seeking persistence

Consider the plight of an attacker who managed to get access to a user account temporarily. That could mean the user forgot to log out of a public machine. Maybe they were phished but they have 2-factor authentication enabled, leaving the attacker holding just 1 valid OTP. (See earlier post on why two-factor authentication with OTP can not prevent phishing.) Or they made a bad decision to use a friend’s PC temporarily to check email and that PC happened to be infected with malware.

In all cases the attacker ends up controlling an authenticated session with the website, having convinced that website they are in fact the legitimate user. The catch is such sessions have a limited lifetime. They can expire for any number of reasons: some sites impose a time limit, others explicitly allow users to logout their existing sessions– Google supports that feature— or trigger logout automatically based on certain events such as a password change. The attacker’s objective is achieving persistence under these circumstances. In other words, extending access to user data as far into the future as possible.

Value of stealth

One option of course is to change the password and lock the original user out. Unfortunately this has the disadvantage of alerting the target that their account has been hijacked. The victim may then take steps to recover, contacting the service provider and even alerting their friends out-of-band.

The “ideal” solution is one where attacker can peacefully coexist with the legitimate user, signing into the account and accessing user data freely without locking out the victim or otherwise tipping them off. Staying under the radar has two benefits. First it buys attacker time to download data from the account they just breached; bandwidth limitations mean that pilfering years worth of email could take a while. Equally important, it allows additional user data to accumulate in the compromised account. More incoming email, more pictures uploaded, more documents authored.

Application passwords

One example of such peaceful coexistence is application passwords or application-specific passwords (ASP) in Google terminology. ASPs are a temporary kludge to deal with incompatibilities created by two-factor authentication. Many protocols have been designed and many applications coded on the assumption that “authentication” equals submitting a username and password. They also bet on these c these credentials rarely changes and can be collected once from the user to be repeatedly used without additional prompting. Two-factor schemes introduce a secondary credential varying over time, breaking that assumption.

If every application had to be upgraded to support the new type of credential, 2FA could not be deployed in any realistic scenario. On the other hand if users were allowed to login with just a password, that would void any benefit of second-factor by leaving open some avenue where it is not enforced. (It turns out Dropbox had exactly this architectural flaw— basic mistakes happen often in our industry.)

Trading compatibility for security

ASP to the rescue. These are randomly generated passwords issued by the service– not chosen by the user. That makes them ideal for “appeasing” applications that demand a password, even when the system has moved on to better-and-safer means of authentication. Why is this better than the good old-fashioned password the user already had? ASPs are randomly generator and not meant to be user memorable. There is no way to phish users for an existing ASP because the user does not know it. Usually it is not even possible to go back and look at previously issued ASPs, except during initial creation. They are displayed generated, entered into the relevant application and promptly forgotten about.

Unintended consequences

Of course if the user can generate ASPs that grant access to email or other resources accessible over a programmatic API, so can the bad guys if they get unauthorized access to the user account. That brings us to option #1 for persistence: create an ASP. Even if the user later logs out all sessions or even changes their password, ASPs remain valid.

There is a catch: the scope of data that can be accessed. Typically an ASP can not be used to sign-in on a web page through the browser; it does not function as a direct replacement for the “real” password. Instead it is used by native applications (desktop or mobile) accessing API endpoints or using a standard protocol such as IMAP to sync email. In fact IMAP is a fairly common offering shared by multiple services. It also happens to be one of the more valuable pieces of user data. Beyond that each service has different API offerings offering access to different resources. For example Google has a “deprecated” proprietary authentication protocol dubbed ClientLogin that accepts ASP and returns authentication tokens suitable for user data.

The second part of this post will focus on a different way to get persistence that does not have this “limitation” of relying on home-brew authentication schemes.



** As an aside: “application-specific” turns out to be a misnomer. Even if the ASP is generated for and only given to the email application, that same ASP can be used by a different application for accessing other resources owned by that user.