How one man could have grabbed your Instagram account

A Belgian bug-hunter just received a $5000 bug bounty after finding an Instagram security flaw.

This story stands in interesting counterpoint to the Slovenian story we wrote about earlier today.

In the Slovenian case, a student found a data leakage bug in the country’s emergency responder network: the TETRA wireless communications network was supposed to be encrypted, but often transmitted data unencrypted by mistake.

The bug wasn’t fixed quickly enough for Dejan Ornig’s liking, so he supposedly used his own security hole to try to make his point more forcefully, ending up poorer by 15 months of suspended prison sentence rather than richer by thousands of dollars.

In this Instagram case, both sides reacted with aplomb.

The researcher, Arne Swinnen, carefully used only his own test accounts when experimenting with the hole he’d found.

In fact, Swinnen wasn’t able to prove his point as precisely as he wanted with any accounts of his own, so he stopped right there and simply invited Facebook (the owners of Instagram) to infer that his vulnerability really would work in real life:

This is the only thing you can do when adhering to responsible disclosure – never touch existing accounts! I explicitly mentioned this to Facebook while reporting, in order to avoid any confusion. I believe this is the responsibility of all bug bounty hunters, despite the fact that it might result in lower bounties in some edge cases. The required trust relationship between researchers and bug bounty providers in the ecosystem relies on this, which is still too often under pressure currently.

Facebook, in its turn, worked with the information Swinnen provided, fixed the problem overnight, and paid him $5000 inside two weeks.

The security hole

Swinnen found the hole when he tried to log into Instagram for the first time in a while and the service asked him to go through the process of re-verifying his account – an understandable precaution used by many websites.

Note that the process described here involves account verification after you’ve connected to a well-known website of your own choosing. Don’t confuse this process with those bogus “account verification” phishing emails that try to trick you into clicking a link in the email to connect to a fraudulent website chosen by the crooks.

Swinnen’s browser showed something like this:

He found that he could change the user ID in the URL at will, and for any user whose account was similarly flagged for verification on next login, a verification screen would appear.

Swinnen had found a security problem, known as an insecure direct object reference, which happens when you can guess, or compute, a URL that gives you access to insider information.

Even if the verification page had subsequently triggered a login prompt, this would have been an exploitable vulnerability, because a crook could try ID after ID to build up a list of “at risk” accounts, an detail that ought to be secret.

Swinnen therefore set out to find out what proportion of account IDs would produce verification pages, trying what he describes as one million IDs from 2,000,000,000 to 2,001,000,000 (actually, that’s one million and one IDs, but we’ll ignore that discrepancy here).

What happened next was interesting: four different sorts of verification screen appeared.

Two were quite different to the one Swinnen saw: instead of requiring you to receive a verification code at an email address or phone number already known to Instagram, they offered the rather self-contradictory option of receiving a verification code to a brand-new address or number.

In other words, crooks could have verified any of those accounts, which came to just over 4% of the one million that Swinnen tried, using contact details of their own.

By doing that, the crooks would not only gain control of the account but also lock out the real owner at the same time.

Even worse, Swinnen noticed that the verification option for 3.88% of the locked accounts included the genuine user’s existing phone number as the default value in the update form:

What to do?

  • Don’t allow write access to user data without authentication.
  • Don’t even allow read access to user data without authentication.
  • Don’t mess with existing accounts when performing security research.
  • Don’t leave vulnerability reports hanging once they’ve been submitted.

Thanks to both parties in this case for their responsive and responsible approach.