REST API Security Reference
Security Design Principles
Based on Saltzer and Schroeder’s foundational paper The Protection of Information in Computer Systems.
Least Privilege
An entity should only have the minimum required permissions to perform authorized actions. Permissions should be granted as needed and revoked when no longer in use.
Fail-Safe Defaults
A user’s default access to any system resource should be denied unless explicitly granted.
Economy of Mechanism
Design should be as simple as possible. Component interfaces and interactions should be easy to understand.
Complete Mediation
Access rights to resources should always be validated. Systems should not rely on cached permission matrices, as outdated permissions can lead to security violations.
Open Design
Security should not rely on secrecy. The system should be designed transparently without hidden algorithms.
Separation of Privilege
Access should not be granted based on a single condition. Instead, multiple conditions should be evaluated based on the resource type.
Least Common Mechanism
Shared state among components should be minimized to prevent corruption from affecting multiple parts of the system.
Psychological Acceptability
Security mechanisms should not interfere with usability. If security makes the system too difficult to use, users may find ways to bypass it.
REST API Security Checklist
Always Use HTTPS
Using SSL/TLS ensures encrypted communication and simplifies authentication using randomly generated access tokens. If HTTP/2 is used, multiple requests can be sent over a single connection, reducing TCP and SSL handshake overhead.
Use Password Hashing
Passwords should always be hashed using secure algorithms such as PBKDF2, bcrypt, or scrypt to mitigate damage in case of a data breach.
Never Expose Sensitive Data in URLs
Usernames, passwords, session tokens, and API keys should never appear in URLs, as they can be logged by web servers and exposed.
Bad:
https://api.example.com/users?apiKey=abcd123456789
Good:
Authorization: Bearer abcd123456789
Input Parameter Validation
Validate request parameters at the very first step before they reach application logic. Implement strong validation checks and reject invalid requests immediately.
Add Request Timestamps
Including a timestamp in API requests as a custom HTTP header can help prevent replay attacks. The server should reject requests with timestamps older than a defined threshold (e.g., 30 seconds).
OAuth 2.0
OAuth 2.0 allows third-party applications to obtain limited access to HTTP services without sharing credentials.
Key Concepts
| Term | Description |
|---|---|
| Resource Owner | User who owns the data |
| Client | Application requesting access |
| Authorization Server | Issues tokens after authentication |
| Resource Server | API that holds protected resources |
| Access Token | Short-lived token for API access |
| Refresh Token | Long-lived token to get new access tokens |
Common Flows
| Flow | Use Case |
|---|---|
| Authorization Code | Server-side web apps (most secure) |
| Authorization Code + PKCE | Mobile/SPA apps (recommended) |
| Client Credentials | Machine-to-machine (no user) |
| Implicit | Legacy SPAs (deprecated, use PKCE) |
Authorization Code Flow
1. App redirects user to Auth Server
GET /authorize?response_type=code&client_id=xxx&redirect_uri=xxx&scope=read
2. User authenticates and consents
3. Auth Server redirects back with code
GET /callback?code=AUTH_CODE
4. App exchanges code for tokens (server-side)
POST /token
grant_type=authorization_code&code=AUTH_CODE&client_id=xxx&client_secret=xxx
5. Auth Server returns access_token and refresh_token
Token Refresh
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=REFRESH_TOKEN&client_id=xxxJWT (JSON Web Tokens)
Compact, URL-safe tokens for transmitting claims between parties.
Structure
header.payload.signature
Header:
{"alg": "HS256", "typ": "JWT"}Payload (Claims):
{
"sub": "user123",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"roles": ["admin"]
}Signature:
HMACSHA256(base64(header) + "." + base64(payload), secret)
Common Claims
| Claim | Description |
|---|---|
sub | Subject (user ID) |
iat | Issued at (timestamp) |
exp | Expiration (timestamp) |
iss | Issuer |
aud | Audience |
Best Practices
- Use short expiration times (15 min - 1 hour)
- Store in memory or httpOnly cookies (not localStorage)
- Validate signature on every request
- Check
expandissclaims - Use RS256 (asymmetric) for distributed systems
Rate Limiting
Protect APIs from abuse and ensure fair usage.
Common Strategies
| Strategy | Description |
|---|---|
| Fixed Window | N requests per time window (e.g., 100/minute) |
| Sliding Window | Rolling window for smoother limits |
| Token Bucket | Tokens refill over time, requests consume tokens |
| Leaky Bucket | Requests queued and processed at fixed rate |
Response Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1609459200Rate Limit Exceeded
HTTP/1.1 429 Too Many Requests
Retry-After: 60Implementation Considerations
- Rate limit by API key, user, or IP
- Different limits for different endpoints
- Higher limits for authenticated users
- Gradual backoff for repeat offenders
API Security Headers
# Prevent MIME sniffing
X-Content-Type-Options: nosniff
# Prevent clickjacking
X-Frame-Options: DENY
# Enable browser XSS filter
X-XSS-Protection: 1; mode=block
# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin
# Content Security Policy
Content-Security-Policy: default-src 'self'
# Strict Transport Security
Strict-Transport-Security: max-age=31536000; includeSubDomainsCommon Vulnerabilities
| Vulnerability | Mitigation |
|---|---|
| Injection (SQL, NoSQL) | Parameterized queries, input validation |
| Broken Authentication | MFA, secure token storage, rate limiting |
| Excessive Data Exposure | Return only needed fields, filter sensitive data |
| Broken Access Control | Validate permissions on every request |
| Mass Assignment | Whitelist allowed fields |
| SSRF | Validate and sanitize URLs, block internal IPs |
| CORS Misconfiguration | Whitelist specific origins, avoid * |