Why Mobile APIs Need Special Protection
Your mobile API is publicly accessible. Anyone with a proxy tool like Charles or mitmproxy can inspect every request your app makes, extract API endpoints, and replay or modify them. Unlike web APIs that can rely partly on CORS, mobile APIs must assume that every request could be crafted by a malicious actor.
Reverse-engineered APKs expose your entire API contract, hardcoded secrets are extracted within hours, and automated bots can hammer your endpoints at scale.
Rate Limiting
Rate limiting controls how many requests a client can make within a given time window. It protects against abuse, prevents resource exhaustion, and ensures fair usage.
Common Algorithms
- Fixed Window - Count requests in fixed intervals (e.g., 100/minute). Simple but allows bursts at boundaries.
- Sliding Window - Tracks requests over a rolling period. Smoother, no boundary burst issue.
- Token Bucket - Clients have tokens that refill at a steady rate. Each request consumes one. Allows short bursts while maintaining average limits. Most common in production.
Rate Limit Headers
Always return rate limit information in response headers:
- X-RateLimit-Limit - Maximum requests allowed in the window
- X-RateLimit-Remaining - Requests remaining in the current window
- X-RateLimit-Reset - Unix timestamp when the window resets
- Retry-After - Seconds to wait before retrying (on 429 responses)
Recommended Limits
| Endpoint Type | Suggested Limit | Window |
|---|---|---|
| Authentication (login/register) | 5-10 requests | per minute |
| Password reset | 3 requests | per hour |
| Standard API reads | 100-300 requests | per minute |
| Write operations | 30-60 requests | per minute |
| File uploads | 10 requests | per minute |
Authentication and Authorization
Token-Based Authentication
JWT is the standard for mobile API authentication. Use short-lived access tokens (15-60 minutes) and long-lived refresh tokens (30-90 days). Store tokens securely in iOS Keychain or Android EncryptedSharedPreferences. Never use plain UserDefaults or SharedPreferences.
OAuth 2.0 with PKCE
For social login, use OAuth 2.0 with PKCE (Proof Key for Code Exchange) to prevent authorization code interception. Use ASWebAuthenticationSession on iOS, Custom Tabs on Android. Never use embedded WebViews.
API Keys
API keys identify the app, not the user. Rotate every 90 days, use different keys per environment, and always combine with user authentication.
Transport Security
All mobile API communication must use HTTPS. Both Apple (ATS) and Google (Network Security Configuration) enforce this by default. Use TLS 1.3 where possible.
Certificate Pinning
Pin the public key (SPKI), not the full certificate, for easier rotation. Always include a backup pin and implement a remote kill switch to disable pinning if a pin becomes invalid.
Input Validation
Validate every input on the server side: type checking, length limits, format validation, SQL injection prevention with parameterized queries, and XSS prevention with content sanitization.
Common Attack Vectors
| Attack | Prevention |
|---|---|
| Brute force login | Rate limit + account lockout |
| API scraping | Rate limiting, bot detection |
| Replay attacks | Timestamps and nonces |
| Man-in-the-middle | TLS + certificate pinning |
| Token theft | Short-lived tokens, secure storage |
| Injection | Parameterized queries, sanitization |
Monitoring
Log all authentication failures with IP and device fingerprint. Set up alerts for unusual traffic patterns. Maintain an IP blocklist updatable without app deployment. Use a WAF (Cloudflare or AWS WAF) as a first line of defense.