Most teams treat API security as an authentication problem. They add tokens, check them on every route, and consider the job done. Then a tester changes one number in a URL and reads another customer’s invoice.
That gap between “authenticated” and “authorised” is where the majority of real API breaches live, and it is not something a scanner finds reliably. An automated tool sees a valid token and a 200 response and reports success. Only a human who understands your business rules notices that the response contained somebody else’s data.
The core distinction: Authentication proves who is calling. Authorisation decides what that specific caller may see or change, and it has to be enforced on every object, on every request, at the data layer. Nearly every serious API vulnerability is a failure of the second thing while the first works perfectly.
Broken Object Authorisation, and Why It Dominates
The single most common serious API flaw is also the simplest to describe.
Your endpoint is /api/invoices/48213. The caller is authenticated, so the handler fetches invoice 48213 and returns it. Nobody checks that invoice 48213 belongs to the caller. Change the number, get someone else’s invoice. The API behaved exactly as written; the writing was wrong.
This scales badly in your favour and well in an attacker’s. Sequential identifiers let someone enumerate your entire dataset with a loop. Switching to unguessable identifiers helps a little but is not a fix, because identifiers leak through other endpoints, exports and emails.
The fix is structural rather than incidental. Ownership must be checked in the query itself — fetch the invoice belonging to this customer with this identifier, rather than fetching the invoice and then hoping something later checks. Put that enforcement in the data access layer so it cannot be forgotten in a new controller written six months from now by someone who has never read this paragraph.
The same failure applies to functions, not just objects. If an administrative endpoint is protected only by the fact that the admin interface does not link to it for normal users, it is not protected at all.
The API Security Flaws That Actually Come Up
Beyond authorisation, a handful of issues account for most findings. The OWASP API Security Top 10 is the standard reference here and OWASP revises it periodically, so check the current edition rather than a summary.
Returning more than the interface shows. An endpoint returns the full user object because that was convenient, and the front end displays three fields. The other twelve, including the password reset token and the internal risk score, are still in the response. Anyone reading the network tab has them. Serialise deliberately: build the response from named fields rather than dumping a model.
Mass assignment on the way in. The mirror image. A profile update endpoint accepts whatever fields arrive and writes them to the record, so a caller adds "role": "admin" and promotes themselves. Bind explicitly to an allowed list of fields rather than accepting the request body wholesale.
Unrestricted consumption. Without limits, one caller can request a million records per page, run expensive searches in a loop, or trigger password resets by the thousand. This is not only a denial-of-service concern; where each request costs you money, as with a language model behind your endpoint, it is a billing attack. Rate limits belong per consumer and per endpoint, with the expensive operations limited more tightly than the cheap ones.
Inventory and Third-Party Trust
Undocumented and forgotten endpoints. Version two is live and documented, version one is still running with the old authorisation logic, and a staging API with production data is reachable from the internet. Attackers look for exactly this. Maintain an inventory of every deployed API, every version and every environment, and decommission deliberately rather than by neglect.
Trusting the systems you call. Your API consumes other APIs, and their responses land in your database and your rendering. Validate what comes back rather than assuming a partner is safe. Our guide to third-party API integration covers the reliability side of the same relationship.
Getting Authentication Right
Authentication is the part most teams get roughly right, so this is about the details that undo it.
Use short-lived access tokens with refresh, not long-lived keys that never expire. A leaked credential that works forever is a permanent breach; one that expires in fifteen minutes is an incident with a bounded end.
Scope tokens narrowly. A token issued to a reporting integration should not be able to create users. Scopes let you enforce that centrally instead of relying on each handler to check.
Validate tokens properly, which mostly means not accepting the algorithm the token itself claims. Pin the expected signing algorithm, verify the issuer and audience, and check expiry. Libraries that do this by default exist; hand-rolled verification is where the mistakes live.
Rotate credentials on a schedule and provide a way for consumers to rotate without downtime, usually by supporting two valid keys during a changeover. If rotation causes an outage, nobody will do it.
Finally, never put credentials in URLs. Query strings end up in server logs, browser history, proxy logs and referrer headers. Use headers.
What a Penetration Test Actually Finds
Automated scanning and manual testing find different things, and you need both for different reasons.
Scanners are good at known vulnerable dependencies, missing security headers, TLS misconfiguration and obvious injection. Run them continuously in your pipeline, because they are cheap and they catch regressions.
What they cannot do is reason about your business. A tester finds that a discount code endpoint can be called repeatedly to stack discounts, that a paid feature is reachable on a free plan by calling the API directly, or that cancelling an order after dispatch triggers a refund without a stock check. Those are the findings that cost real money, and they only surface when someone understands what your API is for.
For an API specifically, ask that the test include authorisation testing across roles, meaning the tester holds credentials for two different customers and systematically tries to reach one account’s data with the other’s token. That single exercise finds more than everything else combined. Our overview of penetration testing types explains how much access to give a tester, and giving them documentation and credentials produces far better results than a blind test.
Budget-wise, API-focused testing typically runs from around £3,000 for a small, well-documented API to £15,000 or more for a large surface with several roles and integrations. Our penetration testing cost guide breaks down what drives that range.
Logging Enough to Investigate
The difference between an incident and a catastrophe is usually whether you can reconstruct what happened.
Log authentication events, authorisation failures, and every state-changing operation with the caller identity, the target object and a correlation identifier. Authorisation failures in particular are your early warning: a legitimate integration produces almost none, so a burst of them is somebody probing.
Do not log the sensitive values themselves. Tokens, card details and personal data in log files convert a contained breach into a reportable one.
Alert on the patterns rather than the volume. A single caller generating authorisation failures across many object identifiers is enumeration in progress, and that is worth waking someone for. Total error rate is not.
Retain long enough to be useful. Compromises are frequently discovered weeks after they begin, and thirty days of logs is often too short to find the entry point.
Test the API You Actually Shipped
Mecanik provides application security testing with a focus on the authorisation and business-logic flaws that automated tooling misses, including cross-account testing with real credentials across roles.
We work from your specification and documentation rather than guessing at the surface, which finds undocumented endpoints and version drift as a side effect. Where the work extends to infrastructure and network testing, our penetration testing services cover that ground. And if you are still designing the API, our custom API development cost guide sets out where authorisation, rate limiting and logging belong in the build rather than being retrofitted.
Send us the specification and a description of your roles, and we will tell you where the risk concentrates.
Related reading: WordPress Hacked: Malware Removal and Recovery Guide , GDPR Technical Compliance for UK Developers in 2026 , Cloudflare Zero Trust: Enterprise Access Security Guide and Penetration Testing in the UK - What to Expect in 2026 .
Frequently Asked Questions
What is the most common API security vulnerability? Broken object level authorisation, where an authenticated caller can reach another user’s data by changing an identifier in the request. Authentication works correctly, but nothing verifies that the requested object belongs to the caller, so ownership must be enforced in the query itself.
Do API keys provide enough security? Not on their own. Long-lived keys that never expire turn any leak into a permanent breach. Use short-lived access tokens with refresh, scope them to what the consumer actually needs, support rotation without downtime, and always send them in headers rather than URLs.
Can automated scanning secure an API? No, though it is worth running continuously. Scanners find known vulnerable dependencies, missing headers and obvious injection. They cannot reason about your business rules, so they miss stacked discounts, paid features reachable on free plans and cross-account data access.
How much does API penetration testing cost? Typically from around £3,000 for a small, well-documented API up to £15,000 or more for a large surface with multiple roles and integrations. Cost is driven by the number of endpoints, the number of distinct roles and whether documentation and credentials are provided.
What should an API log for security purposes? Authentication events, authorisation failures and every state-changing operation, each with caller identity, target object and a correlation identifier. Never log tokens or personal data. Alert on one caller producing authorisation failures across many identifiers, which indicates enumeration.
Comments