REST API Security Best Practices
A comprehensive guide to securing your REST API from authentication to OWASP Top 10
Why API Security Matters
APIs are the #1 attack surface for modern applications. Every API endpoint is a potential entry point for attackers. A single security vulnerability can expose sensitive user data, enable account takeovers, and result in catastrophic breaches.
APIs Are the Primary Target
Over 90% of web applications use APIs. Attackers specifically target APIs because they expose business logic and data directly, often with less protection than traditional web interfaces.
Cost of an API Breach
The average cost of a data breach exceeds $4 million. API breaches often expose bulk data β not just one record, but potentially millions of user accounts in a single attack.
OWASP API Security Top 10
The Open Web Application Security Project maintains a dedicated API Security Top 10 list (2023). Understanding these risks is the foundation of API security.
Compliance Requirements
GDPR, HIPAA, PCI-DSS, and SOC 2 all require robust API security controls. Failure to comply can result in significant fines and legal liability.
Always Use HTTPS
HTTPS is non-negotiable for production APIs. Never serve API endpoints over plain HTTP β it exposes tokens, credentials, and data to network eavesdropping.
π Enforce HTTPS Everywhere
Strict-Transport-Security: max-age=31536000; includeSubDomains
http://api.example.com/users
The HSTS header forces browsers to use HTTPS for your domain for one year. Enforce HTTPS at the infrastructure level (load balancer/CDN), not just application level.
π TLS Configuration
Use TLS 1.3 for new deployments. Disable older protocol versions. Rotate TLS certificates automatically using Let's Encrypt or your cloud provider's certificate manager.
Authentication: Verify Who Is Calling
Authentication verifies the identity of the caller. See our full Authentication guide for implementation details. Here are the security rules that apply regardless of method.
Simple but Limited
Long-lived static credentials. Easy to implement but carry risks: no expiry by default, easy to leak via version control or logs.
Authorization: Bearer api_key_xyz789abc
Stateless & Expirable
Self-contained tokens with expiry. Verifiable without database lookups. Use short-lived access tokens (15 minβ1 hour) with refresh token rotation.
Authorization: Bearer eyJhbGci...
Industry Standard
Delegated authorization framework. Best for third-party integrations. Never implement your own OAuth β use a proven identity provider.
scope: read:users write:orders
Authentication Security Rules
π« Never Put Keys in URLs
GET /api/users?api_key=secret123
Authorization: Bearer secret123
URLs are logged by web servers, proxies, and browser history. Any credential in a URL is immediately compromised.
β° Short Token Expiry
expires_in: 900 (15 minutes)
expires_in: 2592000 (30 days)
Short-lived access tokens limit the damage of a stolen token. Refresh tokens should rotate on each use.
π Secrets Management
const secret = "hardcoded_secret";
process.env.JWT_SECRET
Store secrets in environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault). Never commit secrets to version control.
Input Validation & Injection Prevention
Never trust client-provided data. Validate every input on the server side β type, length, format, and range. Client-side validation is UX; server-side validation is security.
π Validate All Input
age: integer, min: 0, max: 150
age: "'; DROP TABLE users; --"
Use a validation library (Joi, Zod, class-validator) to define strict schemas. Reject requests that don't conform to the expected structure.
π‘οΈ SQL Injection Prevention
WHERE name = '${req.body.name}'
WHERE name = $1, [req.body.name]
Always use parameterized queries or an ORM. Never concatenate user input into SQL strings.
π Content-Type Validation
Content-Type: application/json
Reject requests with unexpected Content-Type headers. This prevents attackers from sending malicious payloads disguised as valid requests.
π Limit Payload Size
express.json({ limit: '100kb' })
Set strict limits on request body size. Without limits, attackers can send gigabyte payloads to exhaust memory.
Rate Limiting & Throttling
Rate limiting is security, not just performance. Without it, attackers can brute-force passwords, enumerate resources, and perform DDoS attacks against your API.
- Apply rate limits per authenticated user, per IP, and globally
- Stricter limits on authentication endpoints (login, password reset)
- Return 429 Too Many Requests with
Retry-Afterheader - Implement at API gateway level, not just application code
- Different rate limits for different tiers (free vs paid)
See our comprehensive Rate Limiting guide for implementation details and algorithms.
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retry_after": 60
}
}
CORS Configuration
Cross-Origin Resource Sharing (CORS) controls which domains can make browser requests to your API. Misconfigured CORS is a common security vulnerability.
β Allowlist Specific Origins
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Using * with credentials allows any website to make authenticated requests as your user. Always allowlist specific origins in production.
π Validate Origin Server-Side
const allowed = ['https://app.example.com', 'https://www.example.com'];
Check the Origin header against a server-side allowlist. Reflect the origin back only if it's in the allowlist β never blindly reflect any origin.
Sensitive Data Protection
Never Log Request Bodies
Request bodies may contain passwords, tokens, credit card numbers, and PII. Log request metadata (method, path, status code, timing) but never the body content.
Mask Sensitive Fields
Partially mask sensitive data in API responses: "card_number": "****1234". Never return full card numbers, SSNs, or passwords in responses.
Paginate Responses
Never return unlimited records from any endpoint. Always enforce pagination limits to prevent bulk data extraction attacks.
No PII in URLs
Avoid /users?ssn=123-45-6789 β URLs are logged everywhere. Put sensitive identifiers in the request body or use opaque tokens.
OWASP API Security Top 10 (2023)
The OWASP API Security Top 10 is the definitive reference for API vulnerabilities. Every API developer should be familiar with all 10 risks.
Security Headers
Set these HTTP response headers to protect against common browser-based attacks. These are in addition to authentication and authorization controls.
| Header | Recommended Value | Purpose |
|---|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains |
Force HTTPS for 1 year |
X-Content-Type-Options |
nosniff |
Prevent MIME type sniffing |
X-Frame-Options |
DENY |
Prevent clickjacking |
Content-Security-Policy |
default-src 'self' |
Prevent XSS attacks |
Referrer-Policy |
strict-origin-when-cross-origin |
Limit referrer header leakage |
Permissions-Policy |
geolocation=(), camera=(), microphone=() |
Disable unused browser features |
API Security Checklist
Use this checklist before deploying any API to production. Every item checked is a class of attacks prevented.
π Transport Security
- HTTPS enforced with HSTS header
- TLS 1.2 minimum, TLS 1.3 preferred
- HTTP requests redirected to HTTPS
- Valid, up-to-date TLS certificate
π Authentication
- All non-public endpoints require auth
- API keys/tokens not in URLs or source code
- Short expiry on access tokens
- Refresh tokens rotate on use
π‘οΈ Authorization
- Resource ownership checked on every request
- No BOLA/IDOR vulnerabilities
- Admin functions protected by role checks
- Principle of least privilege applied
β Input Validation
- All inputs validated server-side
- Parameterized queries (no SQL injection)
- Request body size limits enforced
- Content-Type header validated
π¦ Rate Limiting
- Rate limits on all endpoints
- Stricter limits on auth endpoints
- 429 with Retry-After header
- Implemented at gateway level
π Data Protection
- No sensitive data in logs
- Sensitive fields masked in responses
- Pagination enforced on all list endpoints
- PII not exposed in URLs
Frequently Asked Questions
What is the most common REST API security vulnerability?
Broken Object Level Authorization (BOLA/IDOR) is the #1 vulnerability per OWASP API Security Top 10. It happens when an API returns data for any ID without verifying the requesting user has permission. Fix: always cross-reference the requested resource ID with the authenticated user's identity.
How do I prevent IDOR (Insecure Direct Object Reference) attacks?
Always include the authenticated user's ID in database queries, not just the resource ID. For example: WHERE id = $1 AND user_id = $2. Additionally, consider using UUIDs instead of sequential integers to make IDs unpredictable.
Should I use JWT or sessions for REST API authentication?
JWT is generally preferred for REST APIs because it is stateless β no server-side session storage needed. Use short-lived access tokens (15 min to 1 hour) with refresh token rotation. However, JWTs cannot be invalidated before expiry without additional infrastructure, so sessions may be better for high-security applications that require instant logout.
How do I test my REST API for security vulnerabilities?
Use a combination of automated and manual testing: OWASP ZAP for automated vulnerability scanning, Burp Suite for manual penetration testing, and dedicated API security scanners. Also see our API Testing guide for comprehensive testing strategies. Always test your authentication bypass, IDOR, and injection vulnerability scenarios.