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.

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 2019 USPS case was the same fundamental error as dozens of high-profile breaches before and since — Venmo, Instagram, Facebook, LinkedIn — just with the names changed.

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.


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. gRPC and other patterns exist for internal service-to-service communication.

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

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 is the most current, having been updated from the original 2019 list.

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 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.

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, not just at the route level.

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: none accepted
  • Missing multi-factor authentication for sensitive operations

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 look at the API documentation, examine JavaScript bundles, or watch network traffic during normal use to identify endpoint patterns, then test whether privileged endpoints enforce authorization.


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)
  • Transmitted only in headers (never in URLs, which are logged)
  • Rotatable without disrupting service
  • Revocable individually
  • Scoped to specific permissions where possible

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

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
No revocation Stolen tokens remain valid until expiry Implement token blacklist 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, not secret)

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

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.


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) called thousands of times per minute

Effective rate limiting implementation:

Limit by client identity, not just by IP address. IP-based rate limiting is bypassable via proxies and distributed botnets. API key or user ID-based limiting is harder to circumvent.

Apply limits per endpoint, calibrated to the cost of that endpoint. A simple read endpoint might allow 1000 requests per minute; a password reset endpoint should allow perhaps 5 per hour per account.

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.

Implement progressive delays for authentication failures: after N failed attempts, require exponentially increasing wait times or CAPTCHA challenges.

Log rate limit events for security monitoring: a burst of 429 responses from a single IP is a signal of automated attack.


Input Validation

Every API endpoint that accepts data must validate that data before processing it. This sounds obvious, but 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?

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 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
# 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])

Schema Validation

For REST APIs serving structured JSON, schema validation using JSON Schema or your framework's built-in validation middleware provides systematic coverage. OpenAPI (Swagger) specifications can be used to auto-generate validation middleware, ensuring that all endpoints validate against their documented schemas.


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. The defense is explicit allowlisting of which fields a given endpoint is permitted to update.

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$...",    // should never be returned
  "internal_notes": "flagged user"  // should never be returned
}

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.

Security Misconfigurations

Common API misconfigurations that create vulnerabilities:

  • CORS misconfiguration: allowing all origins (Access-Control-Allow-Origin: *) on endpoints that should be restricted
  • 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, or file paths
  • Default credentials: demo or development credentials left enabled in production
  • Missing HTTPS: API traffic served over plain HTTP

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.

Dynamic testing: testing the running API by sending crafted requests and analyzing responses. The OWASP ZAP (Zed Attack Proxy) and Burp Suite are widely used tools for API dynamic testing.

Fuzzing: sending unexpected, malformed, or boundary-case inputs to discover how the API handles them. Unexpected inputs often reveal validation gaps and error handling issues.

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.

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, 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.

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.


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:

  1. Authenticate every request — verify identity on every call, not just at login
  2. Authorize every operation — check that this user can perform this action on this object
  3. Validate all input — type, format, length, range; reject everything that does not match
  4. Rate-limit everything — especially authentication, password reset, and resource-expensive endpoints
  5. Return minimal data — expose only what the client needs; never return raw database objects
  6. Log and monitor — security events, rate limit hits, and unusual patterns are only visible if logged
  7. Keep an inventory — know what APIs exist, what versions are deployed, and decommission what is not needed
  8. Test for authorization — automated tests that verify authorization checks are as important as tests that verify functionality

The attack surface exposed by APIs is real and growing. The USPS breach, and hundreds like it, demonstrate that the vulnerabilities are not exotic or theoretical. They are fundamental design errors that are avoidable with consistent application of well-understood principles.

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.