At our engineering team, we have been building an autonomous browser agent that navigates the web to test checkout and subscription flows. Recently, we pointed our test runner at a major subscription video streaming platform to analyze how it handled user authentication.
What started as a routine crawler testing run ended in the discovery of two significant API vulnerabilities: a High-severity Account Takeover (ATO) via OTP brute forcing and a Medium-severity SMS Flooding/DoS vulnerability.
Here is the step-by-step breakdown of how we intercepted the auth flow, reverse-engineered the rate-limiting rules, and proved that a simple IP rotation completely bypasses the platform's defenses.
1. Intercepting the Auth Flow
Because the service is a subscription streaming platform, user registration is required before arriving at any checkout screen. To understand how they authorize users, we used a Playwright network interception script to capture traffic during a standard login attempt.
We uncovered a 4-step API chain pointing to their authentication service:
- Guest Registration: POST /api/v1/user/guest/register returns an anonymous session ID.
- OTP Generation: POST /api/v1/user/auth/generateOTP triggers a 4-digit OTP code sent to the mobile number.
- OTP Validation: POST /api/v1/user/auth/validateOTP validates the code.
- Subscription Status: POST /api/v1/subscription/current pulls the active subscription details.
2. Reverse-Engineering the Rate Limiter
Once we mapped the API, we wrote a script to stress-test the rate limits on both the OTP generation and validation endpoints. We ran three scenarios:
- Scenario A: Brute-force wrong OTP codes to measure the validation lockout threshold.
- Scenario B: Spam the resend OTP endpoint to measure the generation lockout threshold.
- Scenario C (Identity Bypass): Rotate the session identifiers (deviceId and session tokens) while keeping the same source IP to see if the counter resets.
The Results:
- Validation Limit: The API allowed 5 incorrect attempts before returning an HTTP 429 API rate limit exceeded message with a variable retry-after cooldown (between 10s to 20s).
- Generation Limit: The API allowed 5 SMS requests before lockout, but with a tiny 3-second cooldown.
- Identity Bypass: Rotating session-specific device IDs did not bypass the limit. The API gateway successfully tracked requests by the client's source IP.
But this IP-only protection introduced a massive vulnerability.
3. The Vulnerability: Account Takeover (ATO)
Because the rate limit is tied solely to the client IP address and not to the target phone number, the system is highly vulnerable to distributed brute-forcing.
The platform uses a 4-digit OTP (only 10,000 possible combinations, from 0000 to 9999). If a malicious actor wants to compromise a specific phone number, they don't need to bypass the IP rate limit—they just need to rotate their IP.
The Math:
- Lockout rate: 5 attempts per IP before a temporary block.
- Evasion: By rotating requests through a residential proxy pool of 100 IPs, an attacker can execute 500 attempts every 20 seconds.
- Time to Compromise: $$\frac{10,000 \text{ combinations}}{1,500 \text{ attempts/minute}} \approx 6.6 \text{ minutes}$$
- Cost: Extremely low cost for residential proxy bandwidth.
Within 7 minutes, an attacker can exhaust the entire keyspace, validate the correct OTP, and gain a valid authentication token for any registered phone number.
4. SMS Flooding & Denial of Service
Similarly, the 3-second cooldown on the /generateOTP endpoint is trivial to exploit. By routing requests through a rotating proxy pool, an attacker can bypass the 3-second cooldown and flood a victim's phone with thousands of SMS messages per minute.
$$\text{5 SMS} \times \frac{60\text{s}}{3\text{s}} = 100\text{SMS/min per IP}$$ With 10 proxy IPs, that is 1,000 SMS messages sent to a single victim every minute, resulting in severe harassment, carrier costs, and temporary denial of mobile service.
5. Responsible Disclosure & Recommendations
_All testing was strictly restricted to developer-owned SIM cards/phone numbers, and no live user accounts were targeted. We have responsibly disclosed these findings to the platform vendor.
To fix these vulnerabilities, we recommend implementing the following architectural remediations:_
- Implement Account Lockout: Tie the rate limiter to the phone number (identity) instead of just the IP address. Lock the phone number out of the authentication flow after 5 failed validation attempts.
- Increase Entropy: Shift from a 4-digit OTP (10,000 combinations) to a 6-digit OTP (1,000,000 combinations). This increases the search space by a factor of 100, rendering brute-forcing through proxy pools completely impractical.
- Strict Token TTLs: Shorten the OTP validity window to 2 minutes.
- CAPTCHA Gateways: Introduce a reCAPTCHA or Turnstile verification challenge after the first OTP resend attempt on the registration screen.


Top comments (0)