The API That Exposed Everything
A SaaS startup discovered their API was leaking customer data. Not through a sophisticated attack—through a simple enumeration. Change the customer ID in the URL, get another customer's data. No authentication bypass needed. The authorization was just... missing.
APIs are the backbone of modern SaaS. They're also the most common attack vector. OWASP now has a dedicated API Security Top 10 because web application security doesn't fully apply to APIs.
This guide covers API security essentials for SaaS companies—the controls that prevent the breaches you read about in the news.
The OWASP API Security Top 10
Understanding the most common API vulnerabilities is the foundation for securing yours:
Broken Object Level Authorization (BOLA) is the most exploited API vulnerability. It happens when your API checks IF you're authenticated but not WHETHER you're authorized to access THAT specific resource. Always verify the user owns/can access the requested object.
The API Security Checklist
1. Authentication
Why it matters: Authentication verifies identity. Weak auth means anyone can claim to be anyone.
- Use Strong Auth Methods — OAuth 2.0, JWT with proper validation, API keys for service-to-service.
- Validate Tokens Properly — Check signature, expiration, issuer, audience on every request.
- Secure Token Storage — Never store tokens in localStorage for web apps. Use httpOnly cookies.
- Implement Token Expiration — Access tokens: 15-60 minutes. Refresh tokens: days-weeks with rotation.
- Rate Limit Auth Endpoints — Prevent brute force on login, token, and password reset endpoints.
JWTs must be validated on every request: verify signature (use RS256, not HS256 with weak secrets), check expiration, validate issuer and audience claims. Never trust JWT contents without verification—that's the whole point of signing them.
2. Authorization (The Big One)
Why it matters: Authorization checks what an authenticated user can do. Missing authorization = data breach.
- Object-Level Authorization — On every request, verify the user can access THAT specific resource.
- Function-Level Authorization — Verify the user can perform THAT specific action.
- Field-Level Authorization — Don't return fields the user shouldn't see.
- Use User Context — Filter queries by user ID, don't trust client-provided IDs.
- Deny by Default — Require explicit permission, not implicit access.
Bad Pattern:
// User provides customer_id
GET /api/customers/{id}
// Server fetches without checking
return db.customers.find(id)Good Pattern:
// User provides customer_id
GET /api/customers/{id}
// Server verifies ownership
return db.customers.find(
id, user.org_id
)3. Input Validation
Why it matters: APIs trust input they shouldn't. Validation prevents injection and logic abuse.
- Validate All Input — Type, length, format, range for every parameter.
- Use Schema Validation — JSON Schema, OpenAPI validation middleware.
- Reject Unknown Fields — Don't accept fields you didn't expect.
- Sanitize for Storage — Prevent SQL injection, NoSQL injection.
- Validate File Uploads — Type, size, and scan for malware.
4. Rate Limiting and Throttling
Why it matters: Without limits, attackers can enumerate data, brute force auth, or DoS your service.
- Per-User Rate Limits — Limit requests per user/API key per time window.
- Per-IP Rate Limits — Backup protection for unauthenticated endpoints.
- Endpoint-Specific Limits — Stricter limits on auth, search, and expensive operations.
- Response Headers — Return rate limit status (X-RateLimit-Remaining, etc.).
- Graceful Degradation — Return 429 with Retry-After, don't just drop connections.
Rate limiting isn't just about DoS protection. It prevents data enumeration (trying every customer ID), credential stuffing (testing stolen passwords), and API abuse. Every API needs rate limits.
5. Data Exposure Prevention
Why it matters: APIs often return more data than needed. Over-exposure creates risk.
- Minimal Response Data — Return only fields the client needs.
- Filter Sensitive Fields — Never return passwords, internal IDs, or PII unless necessary.
- Pagination — Don't return unbounded result sets.
- GraphQL Depth Limits — Prevent deeply nested queries that expose too much.
- Audit Response Content — Regularly review what your API returns.
6. Logging and Monitoring
Why it matters: You can't detect attacks or investigate incidents without logs.
- Log All Auth Events — Login attempts, failures, token issues.
- Log Authorization Failures — Someone trying to access resources they shouldn't.
- Log Rate Limit Hits — Potential abuse in progress.
- Include Context — User ID, IP, request ID, timestamp.
- Don't Log Secrets — Never log passwords, tokens, or sensitive request bodies.
- Alert on Anomalies — Unusual patterns should trigger alerts.
7. Transport Security
Why it matters: API traffic contains credentials and data. Protect it in transit.
- TLS 1.2+ Only — No SSL, no TLS 1.0/1.1.
- Strong Cipher Suites — Disable weak ciphers.
- Certificate Validation — Proper cert chain, no expired certs.
- HSTS Headers — Force HTTPS, prevent downgrade attacks.
- Certificate Pinning — For mobile apps, pin your API certificate.
Common API Security Mistakes
Mistake 1: Client-Side Authorization
Hiding UI elements doesn't prevent API access. If the "admin" button is hidden but the admin API endpoint accepts requests, you have no authorization. Every check must happen server-side.
Mistake 2: Trusting Client-Provided IDs
"Give me customer 12345's data" should not work if the user isn't associated with customer 12345. Always verify ownership/access rights on the server—never trust that the client is sending their own ID.
Mistake 3: Verbose Error Messages
"User not found" vs "Password incorrect" tells attackers which usernames exist. "Invalid credentials" for both. Don't leak information through error specificity.
Mistake 4: No Rate Limiting
"Our API is internal" or "We have authentication" aren't excuses. Compromised credentials plus no rate limits equals mass data exfiltration. Every API needs rate limits.
API Security Testing
What to Test
Quick Start: Your First Week
Day 1-2: Inventory Your APIs
List all API endpoints. Which are public? Which require auth? What data do they expose?
Day 3: Authorization Audit
For each endpoint that returns user-specific data: Is object-level authorization implemented? Test by changing IDs.
Day 4-5: Rate Limiting Check
Test each endpoint for rate limits. Implement limits where missing, especially on auth and search endpoints.
Day 6-7: Logging Review
Verify you're logging auth failures and authorization denials. Can you investigate an incident with current logs?
Next Steps
API security is about assuming attackers will call your endpoints directly—because they will. Every protection must happen server-side. Every resource access must be authorized. Every input must be validated.
Start with authorization. BOLA is the #1 API vulnerability for a reason. Audit every endpoint that returns user data and ensure you're checking ownership, not just authentication.
Building secure APIs? vCISO Lite helps you track API security controls, document your security architecture, and demonstrate API security practices to customers and auditors.