The API Security Landscape

Why APIs became the primary attack surface, how API risk differs from classic web-app risk, and the OWASP API Security Top 10 framework this series builds on.

Fifteen years ago, an attacker probing a company looked at web pages: forms, login screens, the HTML a browser rendered. Today they look at the JSON underneath. The browser is just one more client, and behind it sit dozens — sometimes hundreds — of APIs that expose business logic and data directly to whoever can reach them. Mobile apps, single-page frontends, partner integrations, internal microservices, and increasingly autonomous agents all speak the same language: HTTP requests carrying structured data to endpoints that read and write your database.

That shift is the whole reason this series exists. An API is not a smaller, safer version of a web app — it is a more exposed version. It hands the caller a machine-readable contract to your data model, it usually runs without a human watching each request, and it is frequently under-monitored compared with the front door everyone remembers to guard. This first post frames the problem: why APIs are now where attackers spend their time, how API security genuinely differs from traditional web-app security, how to threat-model an endpoint, and the framework — the OWASP API Security Top 10 — that the rest of the series maps onto.


Why APIs are the primary attack surface

Three properties make APIs attractive targets, and they compound.

APIs expose business logic and data directly. A rendered web page is a view — the server decides what HTML to emit, so a lot of data never leaves the building. An API endpoint is the raw contract. GET /api/v1/accounts/4815/transactions returns exactly what the data model holds, serialized. There is no template layer quietly filtering fields. If the endpoint returns an object with internalRiskScore in it, the caller sees internalRiskScore. The attacker reads your schema the same way your own frontend does.

APIs are machine-to-machine. Most API traffic has no human in the loop. A mobile client refreshes a token and pulls a feed; a partner batch job pulls ten thousand records overnight; an agent calls a tool. That means an attacker’s automated probing blends in — there is no “this request looks like a bot” signal when all legitimate traffic is bots. It also means classic human-facing defenses (CAPTCHAs, interstitial warnings, “are you sure?” confirmations) simply don’t apply.

APIs are often under-monitored. Organizations instrument the marketing site and the login page carefully. The /internal/v2/ endpoint that a deprecated mobile build still calls, or the /api/beta/ route left up after a launch, frequently has no alerting, no rate limits worth the name, and no owner. Attackers hunt exactly these forgotten surfaces — which is why inventory is itself one of the top ten risks (more on that below).

Traditional web app                 API-first system
-------------------                 ----------------
browser -> server -> HTML view      many clients -> many endpoints -> data
  server decides what to render       endpoint serializes the model
  one guarded front door              dozens of doors, some forgotten
  human-paced traffic                 machine-paced, automated traffic

The gotcha: the danger is not that APIs are inherently insecure — it is that the view layer that used to hide your mistakes is gone. Over-fetching, weak authorization, and leaky objects that a server-rendered template would have masked are now shipped straight to the client, where anyone with curl and browser dev tools can read them.


How API security differs from web-app security

If you have internalized the classic OWASP Top 10 for web applications — injection, XSS, CSRF, and friends — you know real risks, but you do not yet have API coverage. The two lists overlap, but the center of gravity is different.

Classic web-app security is dominated by problems at the boundary between untrusted input and a trusting interpreter: SQL injection, cross-site scripting, template injection. Those still matter for APIs (we devote a whole post to injection). But the dominant API risk is somewhere the web-app list barely addresses: authorization at the object level.

Consider the difference. XSS is about a browser executing attacker-controlled markup — an API returning JSON to a mobile app has no DOM to poison, so much of the XSS surface evaporates. CSRF depends on ambient browser credentials (cookies) being sent automatically — token-based APIs that require an explicit Authorization header are structurally less exposed. Meanwhile a new class of problem takes center stage: an authenticated, perfectly “logged-in” user asking for an object that isn’t theirs.

GET /api/v1/accounts/4815/statements HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGci...     # a VALID token for user 5000

Nothing here is malformed. The token is genuine, the user is authenticated, the request is well-formed. The only question that matters is: does user 5000 own account 4815? If the endpoint checks that the token is valid but forgets to check that the object belongs to the caller, it hands over another customer’s statements. No injection, no stolen credential, no exploit payload — just a missing ownership check. This is Broken Object Level Authorization, and it is consistently the number-one API risk precisely because it is invisible to input-focused defenses. A WAF sees a clean request. A schema validator sees valid JSON. Only authorization logic that knows who owns what stops it.

That is the mental shift: web-app security asks “is this input safe to process?” API security adds, with much greater weight, “is this authenticated caller allowed to touch this specific object and this specific operation?”


Threat-modeling an API endpoint

Before the specifics, a reusable lens. Threat-modeling an endpoint means answering three questions in order, and never conflating them.

Where are the trust boundaries? A trust boundary is any line data crosses where the level of trust changes — the internet-to-gateway edge, the gateway-to-service hop, the service-to-database call, and the service-to-third-party call when your API consumes someone else’s. Every boundary is a place where assumptions from one side must be re-validated on the other. The classic mistake is trusting a value simply because it arrived from an internal service; “internal” is a network fact, not an authorization decision.

Authentication vs. authorization — keep them separate. These get blurred constantly, and the blur is the vulnerability.

A correctly authenticated user is still subject to both authorization checks on every request. The endpoint above passed authentication and failed object-level authorization — a distinction that matters because the fixes live in different code.

What data and logic does the endpoint expose? Map, per endpoint, exactly which fields go out, which fields can be written, and which business action is triggered. An endpoint that returns a User object may be leaking passwordResetToken or isAdmin because someone serialized the whole model. An endpoint that accepts a User object may let a caller set isAdmin because it binds the whole request body to the entity. And an endpoint that looks harmless in isolation — “add to cart,” “apply promo code” — may expose a business flow that becomes an attack when automated a million times.


The framework: the OWASP API Security Top 10

The OWASP API Security Project maintains a dedicated top-ten list because the general web-app list, as shown above, misses the risks that dominate APIs. The current edition (2023) is the backbone of this series. Here it is, faithfully summarized in plain terms — each entry links to a later post where we go deep.

The framework: the OWASP API Security Top 10
# Risk In one sentence
API1 Broken Object Level Authorization (BOLA) An authenticated caller reaches an object they don’t own because ownership isn’t checked per request.
API2 Broken Authentication Identity itself can be forged, guessed, or bypassed — weak tokens, unverified signatures, unthrottled login.
API3 Broken Object Property Level Authorization The right object, but the wrong fields — leaking properties on read or letting callers set privileged properties on write.
API4 Unrestricted Resource Consumption No limits on requests, payload size, or cost, so callers can exhaust CPU, memory, bandwidth, or your third-party bill.
API5 Broken Function Level Authorization (BFLA) A caller invokes an operation their role should never reach — a user hitting admin routes.
API6 Unrestricted Access to Sensitive Business Flows A legitimate flow (checkout, signup, booking) is abused at scale because the business impact of automation was never limited.
API7 Server-Side Request Forgery (SSRF) The API fetches a caller-supplied URL and can be tricked into reaching internal services or cloud metadata.
API8 Security Misconfiguration Insecure defaults, verbose errors, missing hardening, permissive CORS, or unpatched components across the stack.
API9 Improper Inventory Management Forgotten, undocumented, or unversioned endpoints (old /v1, /beta, debug hosts) that no one is watching.
API10 Unsafe Consumption of APIs Trusting the third-party APIs you call as if their responses were safe, skipping validation on data you didn’t produce.

Two things about this list are worth internalizing. First, authorization owns three of the ten slots (API1, API3, API5) — object-level, property-level, and function-level. That is not a coincidence; it is the empirical center of gravity of API risk. Second, several entries have no analog on the classic web-app list — sensitive business flow abuse (API6), inventory management (API9), and unsafe consumption of upstream APIs (API10) are API-native problems that come directly from the machine-to-machine, distributed nature of the surface.

The gotcha: the Top 10 is a prioritization list, not a checklist you complete once. A single endpoint can carry several of these at once — a forgotten /v1 route (API9) with verbose errors (API8) that leaks another user’s object (API1). Defense in depth means treating them as overlapping layers, not boxes to tick.


How this series is organized

The remaining posts map onto the framework above, grouped so that related risks are tackled together. Roughly eight installments follow:

This series is a companion to the site’s AI Security Engineering series — agents calling tools are API clients, and every risk here applies when the caller is an LLM instead of a mobile app — and to the API Design series, which covers the contract-shaping decisions (versioning, resource modeling, error semantics) that this series then hardens. Good design and good security are the same conversation viewed from two angles.


Key takeaways


Further reading