In 2019, researchers disclosed a vulnerability in the US Postal Service's Informed Visibility API. The flaw was straightforward: the API did not properly verify that users could only access their own account data. Any authenticated user — someone with a valid USPS.com account — could query the API with any other user's account ID and retrieve their personal information, including name, address, phone number, and email. An estimated 60 million users were affected. The vulnerability had been present for over a year before disclosure.
The USPS incident is not unusual. It represents the single most common class of API security failure: an interface that was built to expose data efficiently but was not designed to enforce who can access which data. The same fundamental error has appeared in breaches at Venmo, Instagram, Facebook, LinkedIn, T-Mobile, Peloton, and hundreds of lesser-known services. The names change; the vulnerability class is the same.
APIs have become the dominant architecture for modern software. Mobile apps, web applications, microservices, IoT devices, and third-party integrations all communicate primarily through APIs. This makes API security not a niche concern for security specialists but a fundamental responsibility for every developer and architect working on modern software. Gartner predicted as early as 2022 that API abuse would become the most frequent attack vector for enterprise web application breaches.
The Scale of the API Attack Surface
APIs represent the fastest-growing attack surface in enterprise computing. Salt Security's State of API Security Report (2024) found that 94% of organizations surveyed had experienced an API security incident in the prior twelve months — up from 78% in 2022. The same report found that the volume of API attacks had increased by 167% year over year.
The scale of API exposure is hard to overstate. Akamai, which operates one of the largest content delivery networks, reported in 2023 that over 83% of web traffic it processed was API traffic. Organizations typically have far more APIs than they have documented: the Salt Security report found organizations had an average of 3x more APIs in production than they believed when measured against internal documentation.
"The challenge with API security is not just that APIs are attacked — it is that most organizations do not have complete visibility into what APIs they have exposed, which makes it impossible to know what to protect." — Salt Security, State of API Security Report 2024
What an API Is and Why It Creates Security Challenges
An Application Programming Interface (API) is a defined set of rules that allows one piece of software to communicate with another. When your weather app retrieves the current temperature, it calls a weather service API. When you log in with Google, an OAuth API handles the authentication flow. When a payment processes on an e-commerce site, a Stripe or PayPal API is being called.
REST APIs (Representational State Transfer) are the most common pattern for web and mobile applications: they use standard HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources identified by URLs. GraphQL APIs allow clients to specify exactly what data they need in a flexible query format — which creates additional security considerations around query complexity and depth limits. gRPC and other patterns exist for internal service-to-service communication. Webhooks allow services to push notifications to external endpoints, creating a different attack surface around endpoint verification.
The security challenge with APIs is inherent to their purpose: they are designed to expose functionality and data. A well-designed API is accessible, predictable, and machine-readable — which means attackers can probe, enumerate, and exploit it programmatically at scale in ways that manual web browsing does not allow.
API-specific threats include:
- Automated enumeration: attackers can iterate through thousands of object IDs systematically
- Machine-speed credential attacks: automated password guessing at volumes impossible via web forms
- Schema inference: the predictable structure of APIs allows attackers to understand the data model
- Endpoint discovery: documentation, JavaScript bundles, and network traffic can reveal undocumented endpoints
- Privilege escalation: APIs that expose different data based on permissions must enforce those permissions consistently on every request
- Data harvesting: APIs designed for single-record queries can be systematically scraped to harvest entire datasets
The OWASP API Security Top 10
The Open Web Application Security Project (OWASP) publishes its API Security Top 10 — a ranked list of the most critical API security risks. The 2023 edition represents a significant update from the original 2019 list, reflecting the evolution of the API threat landscape.
| Rank | Vulnerability | Core Problem |
|---|---|---|
| API1 | Broken Object Level Authorization | API accepts object IDs but does not verify access rights to those objects |
| API2 | Broken Authentication | Weak or missing authentication mechanisms allow account takeover |
| API3 | Broken Object Property Level Authorization | API exposes or allows modification of sensitive object properties |
| API4 | Unrestricted Resource Consumption | No rate limiting; DoS or financial damage via excessive requests |
| API5 | Broken Function Level Authorization | Users can call administrative or privileged functions they should not access |
| API6 | Unrestricted Access to Sensitive Business Flows | Bots can abuse business flows (ticket purchasing, account creation) at scale |
| API7 | Server Side Request Forgery | API can be made to request internal resources on behalf of attacker |
| API8 | Security Misconfiguration | Default credentials, verbose error messages, unnecessary HTTP methods enabled |
| API9 | Improper Inventory Management | Outdated or undocumented API versions and endpoints remain accessible |
| API10 | Unsafe Consumption of APIs | The application blindly trusts third-party API responses without validation |
API1: Broken Object Level Authorization (BOLA)
BOLA — also known as Insecure Direct Object Reference (IDOR) in web application contexts — is consistently the most prevalent and highest-impact API vulnerability. The USPS incident described above is a textbook BOLA vulnerability. The pattern is simple:
GET /api/orders/10234 -> returns your order (correct)
GET /api/orders/10235 -> returns someone else's order (BOLA vulnerability)
The API accepts the object ID in the request, but the authorization check only verifies that the user is authenticated (logged in), not that this particular user is authorized to access object 10235. This error appears at scale partly because authorization is often added late in development, inconsistently across endpoints, or left to the API client to enforce (which provides zero protection).
Correct implementation checks on every request: does this authenticated user have permission to perform this operation on this specific object? The check must happen in the business logic layer on every call, not just at the route level or login time.
A documented real-world example beyond USPS: in 2019, Venmo's API allowed any user to query public transaction data from any other user, including financial transaction descriptions. A developer scraped and published 7 million transactions to illustrate the privacy implications. Venmo addressed the default public setting but the underlying API had no access controls at the object level for users who chose to keep data public.
API2: Broken Authentication
Authentication vulnerabilities in APIs include:
- Weak passwords accepted with no minimum complexity enforcement
- No credential stuffing protection: the API allows unlimited password attempts
- Insecure token handling: tokens transmitted in URLs (logged in server logs, browser history, referrer headers), not expiring, or not invalidated on logout
- Weak token algorithms: JWT tokens signed with HS256 using weak secrets that can be brute-forced; JWT tokens with
alg: noneaccepted - Missing multi-factor authentication for sensitive operations
- Predictable token generation: tokens based on timestamps, sequential IDs, or weak random number generators
API5: Broken Function Level Authorization
BFLA is the API equivalent of privilege escalation: a regular user can call administrative endpoints. This often occurs because API routes are developed and documented but authorization checks are applied inconsistently, or because admin endpoints are undocumented but still accessible.
DELETE /api/admin/users/12345 -> should require admin role
-> actually accepts any authenticated token
Discovery is straightforward for attackers: they examine API documentation, inspect JavaScript bundles, or watch network traffic during normal use to identify endpoint patterns, then test whether privileged endpoints enforce authorization. Automated tools specifically designed for API reconnaissance make this process rapid.
API6: Unrestricted Access to Sensitive Business Flows
This category, added in 2023, reflects a class of attacks that target business logic rather than authentication or authorization controls. Examples include:
- Automated ticket-buying bots that purchase all available inventory before legitimate buyers
- Account creation bots that generate thousands of accounts to exploit per-user promotions
- Automated review submission systems that generate fake reviews at scale
- Price scraping that violates competitive intelligence policies
These attacks often use valid credentials and make individually valid requests — making them difficult to distinguish from legitimate traffic without behavioral analysis.
Authentication: OAuth 2.0, JWT, and API Keys
Authentication — proving who is making a request — is the foundation of API security. The right authentication mechanism depends on the use case.
API Keys
API keys are simple shared secrets, typically long random strings, passed in request headers or query parameters. They are appropriate for server-to-server communication where both parties are under the same organization's control, or for public APIs where the key identifies the client application (not the user).
API key security requirements:
- Sufficient entropy (minimum 32 bytes of randomness, generating a 256-bit key)
- Transmitted only in headers (never in URLs, which are logged in server logs, browser history, and network proxies)
- Rotatable without disrupting service
- Revocable individually without affecting other clients
- Scoped to specific permissions where possible
API keys are routinely leaked by accident. A 2023 study by Nightfall AI found that developers accidentally committed API keys and other secrets to public GitHub repositories over 3.5 million times per year. Tools like GitHub's secret scanning (which now automatically revokes detected credentials for major providers) address a portion of this problem.
JWT (JSON Web Token)
JWTs are a self-contained token format that encode claims (who you are, what you can do, when the token expires) in a JSON object, then sign it cryptographically. The server can verify a JWT without a database lookup, making them efficient for stateless authentication.
A JWT consists of three base64-encoded parts separated by dots: header.payload.signature
The payload is base64-encoded but not encrypted — it is trivially readable by anyone who holds the token. This is an important property: sensitive data must never be placed in a JWT payload.
Common JWT vulnerabilities to avoid:
| Vulnerability | Description | Prevention |
|---|---|---|
| Algorithm confusion | alg: none attack; accepting unsigned tokens |
Explicitly configure accepted algorithms; never accept none |
| Weak secret | HS256 secrets short enough to brute-force | Use 256+ bit secrets; prefer RS256 for public verification |
| No expiration | Tokens valid indefinitely | Always set exp claim; use short-lived access tokens (15-60 min) |
| No revocation | Stolen tokens remain valid until expiry | Implement token blocklist or use short expiry with refresh tokens |
| Sensitive data in payload | Payload is base64-encoded, not encrypted | Never store sensitive data in JWT payload (it is readable) |
| Signature not verified | Library bug or misconfiguration accepts any signature | Use well-maintained libraries; test signature verification explicitly |
The alg: none vulnerability, discovered by Tim McLean in 2015, is a stark example of how JWT can be misimplemented: if a library trusts the algorithm specified in the JWT header, an attacker can set alg: none, remove the signature, and forge any claims. This bug was present in multiple JWT libraries and illustrates why JWT security depends heavily on correct implementation rather than just choosing the standard.
OAuth 2.0
OAuth 2.0 is the industry-standard authorization framework for third-party delegation — allowing one application to act on behalf of a user on another service without sharing passwords. It defines several flows for different contexts:
- Authorization Code Flow (for web apps): most secure; exchanges a short-lived authorization code for tokens
- PKCE (Proof Key for Code Exchange): extension of Authorization Code for mobile and SPAs; prevents code interception attacks
- Client Credentials Flow: for machine-to-machine communication without user involvement
- Device Authorization Flow: for input-constrained devices (smart TVs, IoT)
"Use the Authorization Code Flow with PKCE for any client-side or mobile application. The Implicit Flow (which issues tokens directly to the browser) is deprecated and should not be used in new applications."
The Implicit Flow's deprecation (RFC 9700, 2023) reflects real attacks: access tokens in URLs can leak through browser history, referrer headers, and server logs. PKCE eliminates the code interception attack that previously motivated Implicit Flow's use.
Rate Limiting and Throttling
APIs without rate limiting are vulnerable to:
- Denial of service: excessive legitimate or malicious requests overwhelming the server
- Credential stuffing: automated testing of stolen username/password pairs at scale
- Data scraping: programmatic bulk extraction of publicly accessible data
- Resource exhaustion: expensive operations (database queries, file processing, AI inference) called thousands of times per minute
- Account enumeration: systematically testing whether email addresses exist in a system
Effective rate limiting implementation:
Limit by client identity, not just by IP address. IP-based rate limiting is bypassable via proxies, rotating residential proxies, and distributed botnets. API key or user ID-based limiting is significantly harder to circumvent.
Apply limits per endpoint, calibrated to the cost of that endpoint. A simple read endpoint might allow 1,000 requests per minute; a password reset endpoint should allow perhaps 5 per hour per account; an AI-powered search might allow 10 per minute.
Return appropriate HTTP responses: HTTP 429 Too Many Requests with a Retry-After header telling legitimate clients when they can retry. This allows well-behaved clients to back off gracefully without breaking their functionality.
Implement progressive delays for authentication failures: after N failed attempts, require exponentially increasing wait times or CAPTCHA challenges. AWS Cognito, Auth0, and other identity providers implement this by default.
Log rate limit events for security monitoring: a burst of 429 responses from a single IP or user is a strong signal of automated attack activity.
Input Validation
Every API endpoint that accepts data must validate that data before processing it. Input validation failures remain one of the most common sources of API vulnerabilities, ranging from injection attacks to business logic errors.
What to Validate
For every input field:
- Type: is this a string, integer, UUID, email address, date?
- Format: does a date field contain a valid date? Does a UUID match the UUID format?
- Length: is the string within acceptable bounds?
- Range: is the integer within expected values?
- Allowed values: if the field should be one of a fixed set, validate against that set
- Presence: is a required field present?
- Encoding: is the content properly encoded for its type?
Reject unknown fields rather than ignoring them. If your API accepts a user object with name and email, and a request includes an additional role field, the API should return an error rather than silently discarding the unknown field — the intent may be parameter injection.
Injection Prevention
SQL injection, NoSQL injection, and command injection attacks all exploit insufficient input validation. The 2017 OWASP Top 10 placed injection as the #1 web application risk; it dropped to #3 in 2021 but remains one of the most impactful vulnerability classes.
The primary defenses are:
- Parameterized queries (never concatenate user input into query strings)
- Input allowlisting (accept only known-good formats, reject everything else)
- Escaping where parameterization is not available
- ORM usage with parameterized query generation
# Vulnerable: string concatenation into a query
query = "SELECT * FROM users WHERE id = " + user_input
# Safe: parameterized query
query = "SELECT * FROM users WHERE id = ?"
execute(query, [user_input])
GraphQL-Specific Considerations
GraphQL APIs have additional input validation considerations beyond REST. Because clients can specify arbitrary query structures, malicious or poorly considered queries can cause:
- Query depth attacks: deeply nested queries that cause exponential database load
- Query complexity attacks: queries requesting an enormous number of related records
- Introspection abuse: querying the schema to discover all available fields and types
GraphQL APIs should implement query depth limits, query complexity analysis, and consider disabling introspection in production (though this trades discoverability for security in ways appropriate to the use case).
Common Vulnerabilities in Practice
Mass Assignment
Many API frameworks include features that automatically map request fields to object properties. If not properly configured, this allows attackers to set properties that should not be user-controlled:
POST /api/users/me/update
{
"name": "Alice",
"email": "alice@example.com",
"role": "admin"
}
If the API accepts and applies the role field — even though it was not intended to be user-settable — the user has promoted themselves to admin. Mass assignment vulnerabilities have appeared in Ruby on Rails, Django, Spring, and virtually every framework that offers automatic request-to-model binding.
The defense is explicit allowlisting of which fields a given endpoint is permitted to update — never binding all request fields automatically.
Excessive Data Exposure
APIs often return complete data objects and rely on the client to filter what to display. This creates security problems when objects contain sensitive fields that should never leave the server:
GET /api/users/me
{
"id": "12345",
"name": "Alice",
"email": "alice@example.com",
"password_hash": "$2b$10$...",
"internal_notes": "flagged user",
"two_factor_secret": "JBSWY3DPEHPK3PXP"
}
The defense is server-side response filtering: define exactly what each endpoint returns using serialization schemas or data transfer objects, rather than returning raw database objects. This must be enforced at the API layer, not left to the client.
Security Misconfigurations
Common API misconfigurations that create vulnerabilities:
- CORS misconfiguration: allowing all origins (
Access-Control-Allow-Origin: *) on endpoints that should be restricted to specific domains - HTTP methods not restricted: an endpoint that should be read-only accepting POST, PUT, DELETE
- Stack traces in error responses: detailed error messages that expose technology stack, database schemas, file paths, or internal IP addresses
- Default credentials: demo or development credentials left enabled in production
- Missing HTTPS: API traffic served over plain HTTP; all API traffic must use TLS 1.2 or higher
- Missing security headers: Content-Security-Policy, X-Content-Type-Options, X-Frame-Options absent
API Security Testing
Security testing should be part of every API development lifecycle, not a one-time audit.
Types of Testing
Static analysis: automated scanning of source code for common vulnerability patterns (injection risks, hardcoded credentials, insecure configurations). Tools include Semgrep, SonarQube, and language-specific linters. Many CI/CD pipelines now incorporate SAST tooling as a mandatory gate.
Dynamic testing: testing the running API by sending crafted requests and analyzing responses. The OWASP ZAP (Zed Attack Proxy) and Burp Suite Professional are widely used tools for API dynamic testing. Burp Suite in particular has extensive API-testing extensions.
Fuzzing: sending unexpected, malformed, or boundary-case inputs to discover how the API handles them. REST API fuzzers like RESTler (Microsoft Research) and API-specific modules in Burp Suite can automate this. Unexpected inputs often reveal validation gaps and unhandled error conditions.
Authorization testing: systematically verifying that every endpoint enforces authorization correctly — that users cannot access objects they do not own (BOLA), cannot call functions at privilege levels they do not hold (BFLA), and cannot modify properties they do not control. This is the most important and most commonly neglected category.
Penetration testing: structured adversarial testing by security professionals. OWASP's API Security Testing Guide provides a comprehensive methodology. Bug bounty programs, run by companies through platforms like HackerOne and Bugcrowd, use external researchers to discover real vulnerabilities.
The API Inventory Problem
Organizations often do not have complete visibility into their own APIs. OWASP API9 (Improper Inventory Management) reflects a real operational challenge: APIs proliferate across teams, old versions are not decommissioned, and undocumented endpoints accumulate over time. Shadow APIs — endpoints that are technically accessible but not in the official documentation — represent a significant attack surface.
The T-Mobile 2021 breach, in which 76.6 million customers' data was exposed, involved access through an undocumented API endpoint that was not included in the organization's known attack surface. The attacker discovered it through automated reconnaissance.
An API gateway that enforces all traffic to route through a single control point, combined with automated API discovery tools that scan production traffic, helps maintain an accurate inventory of what is actually exposed. Tools like Traceable AI, Salt Security, and Noname Security specialize in API discovery and behavioral monitoring.
API Security at the Architecture Level
Beyond individual vulnerability prevention, API security requires architecture-level decisions:
API Gateway: A dedicated API gateway (Kong, AWS API Gateway, Azure API Management) centralizes authentication, rate limiting, logging, and traffic filtering. It provides a single enforcement point for security policies across all APIs.
Service-to-Service Authentication: Internal microservice APIs also require authentication. Mutual TLS (mTLS), in which both client and server present certificates, provides strong service identity. Service meshes (Istio, Linkerd) automate mTLS between services.
Secrets Management: API keys and credentials used by services must be stored securely — not in code, environment variables, or configuration files in source control. Dedicated secrets management tools (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) provide secure storage, rotation, and audit logging for secrets.
API Versioning and Deprecation: Maintaining multiple API versions without a disciplined deprecation process is a primary cause of API9 (Improper Inventory Management). Version management policies should specify how long old versions are supported, how deprecation is communicated, and how decommissioning is enforced.
Summary: API Security Principles
API security is not a checklist to complete once; it is a set of design principles that must be applied consistently throughout development and operations:
- Authenticate every request — verify identity on every call, not just at login
- Authorize every operation — check that this user can perform this action on this object
- Validate all input — type, format, length, range; reject everything that does not match
- Rate-limit everything — especially authentication, password reset, and resource-expensive endpoints
- Return minimal data — expose only what the client needs; never return raw database objects
- Log and monitor — security events, rate limit hits, and unusual patterns are only visible if logged
- Keep an inventory — know what APIs exist, what versions are deployed, and decommission what is not needed
- Test for authorization — automated tests that verify authorization checks are as important as tests that verify functionality
- Secure service-to-service communication — internal APIs require authentication; use mTLS or equivalent
- Manage secrets properly — store API keys and credentials in dedicated secrets management systems
The attack surface exposed by APIs is real, large, and growing. The USPS breach, the T-Mobile breach, and hundreds like them demonstrate that the vulnerabilities are not exotic or theoretical. They are fundamental design errors that are avoidable with consistent application of well-understood principles — applied from the beginning, not added as an afterthought.
References
- OWASP. (2023). API Security Top 10: 2023. Open Web Application Security Project.
- Salt Security. (2024). State of API Security Report Q1 2024. Salt Security Inc.
- Akamai Technologies. (2023). State of the Internet: API Security. Akamai.
- Gartner. (2022). Gartner Predicts 2022: APIs Drive Connectivity and Security Risk. Gartner Inc.
- McLean, T. (2015). "Critical vulnerabilities in JSON Web Token libraries." Auth0 Blog, March 31.
- IETF. (2023). RFC 9700: OAuth 2.0 Security Best Current Practice. Internet Engineering Task Force.
- Nightfall AI. (2023). 2023 Cloud Data Leak Report. Nightfall AI Inc.
- Shafranovich, Y. (2023). T-Mobile Data Breach Analysis. Internet Crime Complaint Center.
- OWASP. (2023). OWASP API Security Testing Guide. Open Web Application Security Project.
- Microsoft Research. (2022). RESTler: Stateful REST API Fuzzing. Microsoft Corporation.
- National Institute of Standards and Technology. (2024). SP 800-204C: Implementation of DevSecOps for a Microservices-based Application with API. NIST.
- Anti-Phishing Working Group. (2023). APWG Phishing Activity Trends Report. APWG.
Frequently Asked Questions
What is API security and why does it matter?
API security refers to the practices, tools, and protocols that protect application programming interfaces from unauthorized access, misuse, and attack. APIs are the connective tissue of modern software — they expose data and functionality to other applications. Because APIs often provide direct access to business logic and sensitive data, they are a primary target for attackers. Salt Security's 2023 State of API Security Report found that 94% of organizations experienced API security problems in the prior 12 months.
What is Broken Object Level Authorization (BOLA)?
Broken Object Level Authorization (BOLA), ranked first in the OWASP API Security Top 10, occurs when an API endpoint accepts object IDs in requests but does not verify that the requesting user is authorized to access that specific object. An attacker who can access their own account object (e.g., /users/12345) can manipulate the ID to access another user's data (/users/12346). It is the most prevalent API vulnerability because it is easy to introduce and hard to detect without specific testing.
What is the difference between OAuth 2.0 and JWT for API authentication?
OAuth 2.0 is an authorization framework that allows third-party applications to obtain limited access to a service on behalf of a user, without exposing credentials. JWT (JSON Web Token) is a token format — a compact, self-contained way to encode claims that can be verified without a database lookup. They are often used together: OAuth 2.0 defines the flow for obtaining authorization; JWTs are a format for the access tokens that flow is issued. JWT-only authentication without OAuth 2.0 is simpler but lacks standardized revocation and scope mechanisms.
What is rate limiting and why is it important for APIs?
Rate limiting restricts how many requests a client can make to an API within a given time window. It protects against denial-of-service attacks, credential stuffing (automated password guessing), scraping of proprietary data, and resource exhaustion. Effective rate limiting should be applied per client (by API key or IP address), per endpoint (since some endpoints are more expensive than others), and with clear error responses (HTTP 429) and retry-after headers so legitimate clients can back off gracefully.
How should input validation be implemented in APIs?
API input validation should verify that incoming data matches the expected type, format, length, and range before processing it. Validation should occur server-side (not just client-side), for every field, and should reject unknown fields rather than ignoring them. Schema validation using tools like JSON Schema or OpenAPI validation middleware provides systematic coverage. All validation failures should return appropriate error codes (typically HTTP 400 or 422) with descriptions that help legitimate clients but do not expose internal implementation details to attackers.