§ 03 · Guide
What an API penetration test report must contain
The report is the only part of a penetration test that outlives the engagement. It has to survive being read by a board member, argued over by an engineer and filed by an auditor, which is three incompatible jobs. This guide sets out what the document needs in order to do all three, and how to check a sample before you buy.
Four readers, one document
Every complaint about penetration test reports comes from a mismatch between reader and section. A board member handed a 90-page finding list concludes that security is unmanageable. An engineer handed a two-page executive summary cannot fix anything. An auditor handed either one asks for the scope and gets a paragraph.
The fix is structural rather than editorial. A usable report is written in layers, and each layer states plainly who it is for. NIST SP 800-115 places reporting alongside the other phases rather than after them, precisely because the notes that make a good report are written during the attack phase, not reconstructed from memory a fortnight later.
| Reader | Reads | Needs to leave with |
|---|---|---|
| Board or executive | Executive summary | What an attacker could have done, and the two or three decisions that follow |
| CISO or security lead | Summary, attack chains, roadmap | Where the systemic weakness is, and what it costs to remove |
| Engineers | Findings with evidence | A reproducible request, the affected routes and a fix in the right layer |
| Auditor or customer | Scope, coverage matrix, retest statement | Proof that the right things were tested, and that findings were closed |
The seven sections
1. Executive summary
One page. What was tested, over what period, what the most serious realistic outcome was, and what should happen next. No tool names, no severity histogram, no CVSS vectors. If the summary cannot be understood by somebody who has never heard of BOLA, it is not an executive summary, it is an abstract.
2. Scope and coverage matrix
The section auditors read first and vendors most often skip. It states the environment, the dates, the credentials supplied, the endpoints or operations in scope, and then, in a matrix, which of them were exercised from which role. Each crossing is marked tested, not reachable, or excluded, with a reason for every exclusion.
This matters because coverage is the only honest basis for a negative claim. “No broken function level authorization was identified” is meaningless on its own. “No broken function level authorization was identified across 47 administrative operations tested from all five roles” is a statement someone can rely on, and it is the version a certification body will accept.
3. Findings with evidence
Each finding needs: a title that names the flaw and the affected component, a severity score with the vector that produced it, the exact request and response, the account and role the request was sent from, the affected routes enumerated rather than sampled, the business impact in your terms, and a remediation written for the layer that owns the bug. A finding that says “implement proper authorization” has moved the problem, not described a fix.
4. Attack chains
Individual findings understate risk because attackers combine them. An informational identifier leak plus a medium object-level flaw is not one low and one medium; it is a full customer database. The chain section takes the two or three combinations that actually matter and walks them step by step, which is also the part of the report that survives being shown to a non-technical audience.
5. Standards mapping
Each finding mapped to its OWASP API Security Top 10 category and to the relevant OWASP ASVS requirement. The Top 10 mapping is what your questionnaire responses and your customers ask for. The ASVS mapping is what makes the report useful to engineers, because ASVS 5.0 phrases controls as verifiable requirements: chapter V4 covers API and web service security, with sections for generic web service security, HTTP message structure validation, GraphQL and WebSocket.
6. Remediation roadmap
Findings regrouped by root cause and ordered by risk removed per engineering day, not by raw severity. Twelve object-level findings caused by one missing middleware call are one fix, and saying so is worth more than twelve tickets. A roadmap that is just the findings list sorted by CVSS has done no work.
7. Retest statement
What was re-tested, on what date, what is verifiably fixed, what is partially fixed, and what remains open with the customer’s accepted risk noted. This is the artefact that closes an audit finding, and it is the one most often sold as an optional extra. Buy it.
Anatomy of one finding
Here is a broken object level authorization finding written the way it should be. The pattern generalizes to every other category.
Title and severity
“Broken object level authorization on the order resource allows any authenticated user to read any order.” High. The severity line carries the scoring vector so the number can be argued with rather than merely disputed.
Evidence
The request as sent, including method, path, headers with the token redacted, and body. The response with the status line and the fields that prove the leak. The account it was sent from, named and mapped to its role. A second request from the legitimate owner showing the same object, so the reader can see the two responses are identical.
Extent
Not “the order endpoint”, but: the resource, the verbs affected, and how many object types share the same handler. This is the difference between a one-line fix and a fortnight of work, and only the tester who mapped the routes can supply it.
Impact, in your language
What a caller can obtain, at what rate, and what that means for the business. Where a rate limit exists, say what it caps the extraction at; where it does not, say so explicitly. The Dell partner-portal breach is the cautionary version: a single-record lookup issue became 49 million records because the API sustained 5,000 requests per minute for weeks.
Remediation
Named layer, named check. “Enforce ownership in the data access layer for every resource sharing the OrderRepository, rather than in the controller, and add a regression test that requests a foreign identifier from each role” is actionable. “Implement proper access controls” is not.
Verification
How the tester will confirm the fix at retest: the same request, from the same account, expecting a specific status code. Writing this at the time of the finding rather than at retest keeps both sides honest about what closing it means.
At the conclusion of the test, a report is generally developed to describe identified vulnerabilities, present a risk rating, and give guidance on how to mitigate the discovered weaknesses.NIST SP 800-115, section 5.2.1
What a coverage matrix looks like
Vendors describe coverage matrices differently, so it is worth being concrete. The matrix is a grid of the things you can be attacked through against the identities that can reach them, and every cell has a state. Below is a fragment of one for a small multi-tenant API. Real matrices run to several pages, which is exactly why they belong in an appendix rather than in the summary.
| Resource | Anonymous | Customer | Support agent | Second tenant |
|---|---|---|---|---|
| Orders | Tested, denied | Tested, 1 finding | Tested, denied | Tested, 1 finding |
| Invoices | Tested, denied | Tested, denied | Tested, denied | Tested, denied |
| User profiles | Tested, denied | Tested, denied | Tested, denied | Tested, denied |
| Admin operations | Tested, denied | Tested, denied | Not reachable | Tested, denied |
| Webhook registration | Tested, denied | Tested, 1 finding | Excluded: shared sandbox | Not reachable |
Two properties make this section work. Nothing is left blank, so the reader can distinguish a control that held from a control that was never exercised. And exclusions carry their reason inline, so the limitation is documented at the point where somebody would otherwise assume coverage. A matrix with empty cells is worse than no matrix, because it looks like assurance.
The readout matters more than the document
The written report is the artefact; the live readout is what gets things fixed. An hour with the tester, the engineers who own the affected services and whoever prioritizes their backlog turns a list of findings into a set of tickets with owners. It is also the fastest way to resolve disagreements about severity, because the tester can demonstrate the request rather than describe it.
Ask for the readout in the engagement contract, ask for it to be with the engineers rather than only with management, and ask for it to happen before the report is finalized. Findings challenged in a live session get corrected; findings challenged in email two weeks later get deferred.
How an auditor uses the document
A regulator or certification body does not read your findings. It reads the scope, the methodology, the dates and the remediation record, and it checks that they are consistent with what the applicable rule requires.
| Regime | What it looks for | Which section supplies it |
|---|---|---|
| DORA | Yearly testing of systems supporting critical or important functions, by an independent party | Scope, dates, tester independence statement, retest |
| NIS2 and CIR 2024/2690 | A documented test methodology, and the recorded type, scope, time and results of each test | Methodology, coverage matrix, findings, remediation record |
| PCI DSS v4.0.1 | A documented methodology whose application-layer testing covers at minimum the Requirement 6.2.4 attack classes | Methodology, standards mapping, coverage matrix |
| ISO 27001 and SOC 2 | Evidence that technical vulnerabilities are identified and managed | Findings, roadmap, retest statement |
Two practical consequences. First, the methodology section has to name the method, not the tools: an auditor asked to accept “Burp Suite and custom scripts” as a documented methodology will ask what the method was. Second, the retest statement is what converts a list of problems into evidence of a working process, which is the thing all four regimes are actually assessing. The compliance guide goes through each obligation clause by clause.
What a bad report looks like
- Findings you cannot reproduce. No request, no response, no account. Engineering cannot verify it, so it gets disputed and then deferred.
- Scanner output with a cover page. Recognizable by tool-generated titles, generic remediation text and a finding count in the hundreds with nothing above medium.
- No coverage matrix. The report cannot support a single negative statement, so it cannot be used as assurance for anything.
- Severity without context. A base score copied from a vector calculator, with no adjustment for whether the affected data is public marketing copy or medical records.
- A roadmap that is the findings list re-sorted. No root-cause grouping means twelve tickets for one missing middleware call.
- No statement of what was not tested. Silence about exclusions is the most expensive omission in the document, because it will be discovered during an incident.
Questions to ask before you sign
- Can I see a full sample report, redacted if necessary?
- Does the report contain a coverage matrix of endpoints by role, and can I see the format?
- Does each finding carry the raw request and response?
- Are findings mapped to OWASP API Security Top 10 and to ASVS requirements?
- Is a retest and a re-issued statement included, and within what window after delivery?
- Who presents the readout to the engineering team, and is it included?
- What is your policy on re-issuing the report if we dispute a severity rating?
Sources
- Technical Guide to Information Security Testing and Assessment (SP 800-115) Reporting phase and the four-phase structure.
- OWASP API Security Top 10 – 2023
- OWASP Application Security Verification Standard 5.0, V4 API and Web Service
- Regulation (EU) 2022/2554 (DORA)
- Commission Implementing Regulation (EU) 2024/2690 Annex point 6.5, security testing records.
- Dell API abused to steal 49 million customer records
- Sample penetration test report Fictional grey-box report used here as a format example.