A note on examples
What follows is a synthesis of recurring patterns we see across reported API incidents and across our own engagements. Specific company names are not necessary to make the patterns useful — the same flaws show up across industries, with the same root causes and the same fixes. If you want to map this to a specific publicly-disclosed incident, the OWASP API Top 10 supplementary materials and a few public breach databases catalog real cases for each category.
Pattern 1: Broken object-level authorization
The shape. An API endpoint accepts an identifier — user ID, account ID, document ID — and returns the corresponding object. The endpoint authenticates the caller (so the caller must be a logged-in user), but it does not verify that the caller is authorized to read this specific object. Result: any logged-in user can read any object by guessing or enumerating identifiers.
Why it keeps happening. The fix lives at the data-access layer. Frameworks make it easy to put the auth check at the controller and trust that the query returns "the right thing" — which it does, until an identifier is supplied that the user should not access. The query returns the object; the controller never re-checks.
What prevents it. Authorization at the data-access layer, scoped to the caller's identity. Row-level security in the database. ORM scopes that automatically filter by tenant or owner. Default-deny query patterns where the query without an explicit identity filter returns nothing.
Pattern 2: Unrestricted resource consumption
The shape. An API endpoint performs expensive work — search, export, aggregation, image processing — without per-caller limits. An attacker (or a buggy client) submits requests in volume and the service degrades or fails entirely. In other variants, the cost is financial: each request triggers a paid third-party call, and the bill arrives at the end of the month.
Why it keeps happening. Rate limits exist on login but not on internal expensive operations. Pagination has no maximum. Background jobs are triggered synchronously. The system is sized for normal load and folds under malicious load.
What prevents it. Per-identity and per-endpoint rate limits at the gateway. Hard caps on pagination. Async processing with quotas for any operation that costs real money or significant compute. Cost annotations per endpoint so the gateway knows what is expensive.
Pattern 3: API inventory drift
The shape. An old API version, a staging endpoint, or an internal API ends up reachable from the public internet. The old version has weaker auth, missing fixes, or different security posture than the current version. An attacker discovers the old endpoint via DNS, certificate transparency logs, or directory enumeration, and uses it as the entry point.
Why it keeps happening. APIs accumulate. Versions deprecate slowly. Staging hosts persist after they are no longer needed. Documentation diverges from production reality.
What prevents it. Maintain an explicit inventory of API endpoints and versions, with sunset dates. Guard staging with auth at the network or gateway layer. Monitor certificate transparency for hostnames you did not expect to be public.
Pattern 4: Mass assignment via excessive input trust
The shape. A user updates their profile by submitting a JSON object. The backend accepts the entire object and applies it to the database record. The user submits an extra field — role: "admin", verified: true, balance: 99999 — and the backend processes it because it never explicitly rejected unknown fields.
Why it keeps happening. ORMs and frameworks default to permissive input handling. The schema for the response is the same as the input, which makes it easy to accept fields you intended only to return.
What prevents it. Explicit input allow-lists per endpoint and per role. DTOs separate from database models. Response shapers that strip output fields not authorized for the caller.
Pattern 5: Server-side request forgery
The shape. An API accepts a URL — for image fetching, webhook delivery, link previews, file imports — and the server makes the request. An attacker supplies a URL pointing to internal services, cloud-metadata endpoints, or sensitive paths behind the perimeter, and the server's response leaks internal data.
Why it keeps happening. Outbound HTTP feels like a trusted operation; the input is "just a URL". Cloud-metadata services reachable from compute instances make SSRF disproportionately dangerous in cloud environments.
What prevents it. Allow-list of permitted destinations. Strip credentials from outbound requests. Cap or disable HTTP redirects. Use a separate egress proxy with policy enforcement.
Pattern 6: Broken authentication and identity
The shape. Authentication mechanisms are implemented incorrectly. JWT alg confusion. Refresh tokens that work indefinitely after device replacement. Password resets that rely on guessable tokens. Federated login flows that downgrade to weaker local auth. Each is a small mistake that becomes the entry point.
Why it keeps happening. Auth is built once and rarely revisited. Edge cases (recovery, device replacement, federation downgrade) get less attention than the happy path.
What prevents it. Use a well-known auth library; do not roll your own. Validate JWT alg parameters. Rotate refresh tokens on use. Single-use, time-bound reset tokens. Test the full identity surface, not just the login form.
Practical best-practice checklist
Twelve items that, if applied consistently, prevent most of what we see in real engagements:
- Authorization at the data-access layer, not at the controller.
- Default-deny query patterns scoped to caller identity.
- Explicit input allow-lists per endpoint and per role.
- DTOs separate from database models for both input and output.
- Per-identity and per-endpoint rate limits at the gateway.
- Hard maximums on pagination and batch operations.
- Inventory of API endpoints and versions with sunset dates.
- Allow-list of outbound URLs; strip credentials; disable redirects.
- Well-known auth library; validate JWT alg explicitly.
- Single-use, time-bound password-reset tokens.
- Audit logs for sensitive operations, with tamper-evidence.
- Annual third-party API penetration testing scoped to OWASP API Top 10 plus business-logic abuse cases.
The honest summary: most reported API breaches do not exploit novel categories of bug. They exploit the same handful of patterns repeatedly. The fix list is short and well-known. The work is making it consistent across every endpoint your team has shipped, including the ones from two years ago that nobody reads anymore.
API testing
REST, GraphQL, and webhook surfaces — auth, IDORs, rate limits, tenant isolation, mapped to OWASP API Top 10.
See the engagement Common in this industryE-commerce & retail
Account takeover, promo abuse, payment-flow integrity, customer-data protection.
See industry scopeRelated articles
Preparing for your first pentest? Download the SMB Pentest Readiness Checklist →