Broken object-level authorisation
Every endpoint that accepts an identifier is tested against objects belonging to other users and other tenants. This is the finding that ends careers.
Application Security
The user interface is a suggestion. The API is what actually enforces your rules — and it answers requests that no screen in your product would ever send.
A web application has a shape. There are pages, they link to each other, and a user moves through them in roughly the order the designers intended. An API has no such shape. It is a set of endpoints that will each answer any request that reaches them, in any order, from any client, with any parameters — and the only thing standing between a well-formed request and your data is whether somebody remembered to check authorisation on that specific route.
That is why broken object-level authorisation sits at the top of the OWASP API Security Top 10 and why it is still, by a distance, the most common critical finding we report. The pattern is always the same: an endpoint validates that you are logged in, and then trusts the identifier you sent it. Change the number, get somebody else’s record. It is trivial to exploit, it is invisible to a scanner that has no idea which records belong to whom, and it is catastrophic when the records are invoices, prescriptions or KYC documents.
We test APIs against their specification where one exists, and reconstruct one where it does not. Every endpoint, every method, every parameter, every role — including the endpoints that are deployed but undocumented, which in our experience is most of the interesting ones.
Coverage
Coverage follows the OWASP API Security Top 10, extended for GraphQL and internal service-to-service traffic.
Every endpoint that accepts an identifier is tested against objects belonging to other users and other tenants. This is the finding that ends careers.
Administrative and privileged routes probed with lower-privilege tokens, including methods the documentation does not list.
JWT signature and algorithm handling, token expiry and revocation, refresh flows, API key scoping, and OAuth implementation errors.
Responses returning more fields than the client displays — the classic case where the front-end hides what the server happily sends.
Missing throttling, unbounded pagination and expensive queries that make a single request costly to serve.
Introspection exposure, deeply nested and recursive queries, batching abuse, and field-level authorisation that is enforced inconsistently across resolvers.
Object properties that can be set through the API but were never meant to be client-controlled — role, balance, verified, is_admin.
Operations replayed, reordered or invoked out of sequence, and state transitions that the API permits but the product does not.
Approach
Faster than a full application test when a specification exists, because coverage can be driven from it directly.
OpenAPI, Swagger, Postman collection or GraphQL schema. Where none exists we reconstruct the surface from traffic and client code.
Which identities exist, what each one legitimately owns, and therefore what each one must never be able to reach.
Every documented endpoint and method exercised for known classes, misconfiguration and exposure, with dependency and version issues matched against current intelligence.
The methodical part, and the reason this service exists: every endpoint tested with every role against objects belonging to somebody else.
Sequence, replay, quantity and state-transition abuse, plus consumption testing where availability is in scope.
Findings mapped to endpoints and methods so the fix has an obvious owner, then a free retest.
Deliverables
The report is the product. If it cannot be acted on by a developer and understood by a director, we have not finished.
Every issue names the route, method and parameter, so the fix lands on one team’s backlog without a triage meeting.
A grid of roles against endpoints showing exactly where the boundary held and where it did not.
Copy-paste requests your engineers can replay immediately, not screenshots of a proxy tool.
SARIF and JSON for direct import into your pipeline or ticket queue.
Verification once fixes ship, with per-finding state recorded.
Is this for you?
If none of them are, say so on the call and we will tell you honestly whether this is the right piece of work — or point you at the one that is.
Book a scoping callHow we work
The same engagement model applies to every piece of work we take on, so you always know what happens next.
A 30-minute call, then a written scope: what is in, what is out, what we need from you and what it costs. Nothing starts before you sign it.
Rules of engagement, testing windows, escalation contacts and a signed authorisation. Out-of-hours windows where production cannot take the load.
Automated coverage first, then manual testing where judgement is required. Critical findings are reported the day we confirm them, not at the end.
One report a developer can act on and an executive can read, with evidence, reproduction steps, business impact and a fix for every finding.
A walkthrough call with your engineers. We answer questions on the fix, not just the finding.
A free retest cycle to confirm the fixes hold, and a clean summary you can hand to a customer, auditor or board.
Questions
The questions clients actually ask during scoping. If yours is not here, ask it directly.
Broken Object-Level Authorisation is when an endpoint confirms that you are authenticated but does not confirm that the specific record you asked for belongs to you. Change an identifier in the request and you receive somebody else’s data. It is the most commonly exploited API flaw, it requires no special skill to abuse, and automated scanners cannot detect it because they have no concept of which records should belong to which user. Finding it requires testing with multiple real accounts, which is exactly how we do it.
It helps a great deal and makes the engagement faster and cheaper. An OpenAPI or Swagger specification, a Postman collection or a GraphQL schema lets us drive coverage directly from the definition. Where documentation does not exist we reconstruct the surface from client applications and observed traffic — that is normal, and the undocumented endpoints we uncover in the process are often the most interesting part of the report.
Yes, and it needs its own treatment. GraphQL moves authorisation down to the resolver level, so a single schema can enforce field access consistently in one place and inconsistently in another. We test introspection exposure, query depth and complexity limits, batching abuse, and field-level authorisation resolver by resolver.
From inside. We either work from a jump host you provide, a VPN connection, or a container we run within your environment. Internal service-to-service APIs are worth testing precisely because they are usually built on an assumption of implicit trust — once an attacker has any foothold, that assumption is doing all the security work.
Testing runs against a non-production dataset wherever one exists. Where production testing is agreed, write and destructive operations are constrained to accounts and records you nominate, and everything we create is recorded so it can be cleaned up afterwards. This is agreed in writing before any request is sent.
Next step
A 30-minute call, then a scope document with what is in, what is out and what it costs. No obligation, and no charge for the conversation.