This is a fictional example

Northwind Analytics, its hostnames, accounts, identifiers, and every finding below are invented for illustration. No real client, product, or engagement is represented here, and no real vulnerability is disclosed. Example domains follow the reserved conventions of RFC 2606.

Client reports are confidential. We never publish, share, or reference a real client\u2019s findings without their written permission, which is why this page uses a fictional subject rather than a redacted real one.

Structure

What the full report contains

A typical report for a SaaS product runs to somewhere between twenty and sixty pages, depending on scope and on how much was found.

Executive summary
One page, written for a reader who will not read further. States the overall position, the most serious findings, and what changed after remediation.
Scope and approach
The assets tested, the environment, the accounts and roles used, the testing window, and the agreed exclusions.
Findings summary
A single table of every finding with severity and remediation status, so the position is visible at a glance.
Detailed findings
One section per finding, in the form shown below on this page.
Observations
Hardening opportunities and design notes, kept separate from confirmed vulnerabilities so the finding count is not inflated.
Limitations
What the scope or timeframe prevented us from examining, stated plainly.
Retest results
The verified status of each finding after your team’s remediation work.
Example — findings summary

The summary table

Every finding in one place, with severity and current status. This is the page most readers go to first.

Fictional example: findings summary for Northwind Analytics, showing status after retest.
Ref Finding Severity Status after retest
NWA-01 Tenant isolation bypass in report export endpoint Critical Fixed and verified
NWA-02 Missing function-level authorization on user invitation API High Fixed and verified
NWA-03 Session not invalidated after password change High Fixed and verified
NWA-04 Cloud storage role grants read access beyond requesting tenant High Partially fixed
NWA-05 Verbose error responses disclose internal object identifiers Medium Fixed and verified
NWA-06 Rate limiting absent on password reset request Medium Fixed and verified
NWA-07 Long-lived API tokens without rotation mechanism Low Risk accepted
NWA-08 Security headers missing on application responses Low Fixed and verified

Note that one item is recorded as partially fixed and one as risk accepted. Real remediation is rarely uniform, and a report that shows every item closed is usually less honest than one that does not.

Example — detailed finding

How a single finding is written

This is the anatomy of a finding: what it is, why it matters to the business, exactly how to reproduce it, what we observed, and what to do about it.

FINDING NWA-01  ·  FICTIONAL EXAMPLE Critical

Tenant isolation bypass in report export endpoint

Summary

The report export endpoint accepts a workspace identifier from the client and returns the corresponding export without verifying that the authenticated user belongs to that workspace. Any authenticated user of any tenant can retrieve exported reports belonging to any other tenant by substituting the identifier.

Affected component

GET /api/v2/workspaces/{workspace_id}/exports/{export_id} — export service, authorization middleware not applied to this route

Business impact

A customer on the lowest-priced plan can read the exported analytics of every other customer on the platform, including any commercially sensitive data those reports contain. This is a confidentiality breach across the tenancy boundary, likely to be reportable under data protection obligations, and likely to be material in enterprise contracts that warrant tenant separation.

Exploitation requires nothing beyond a valid account on any tenant and knowledge of a workspace identifier. Identifiers are sequential and are disclosed in application responses, so enumeration is straightforward.

Severity reasoning

Rated Critical: exploitable by any authenticated user with no additional privilege, requires no user interaction from the victim, is reliably reproducible, and results in unauthorized access to other tenants\u2019 data. Cross-tenant confidentiality failure in a multi-tenant product is the highest-consequence class of finding for this architecture.

Reproduction steps

  1. Authenticate as analyst@tenant-b.example.com (Analyst role, Workspace 4102).
  2. Request GET /api/v2/workspaces/4102/exports/ and note the response format and an export identifier.
  3. Substitute a workspace identifier belonging to another tenant, for example 3871, retaining the same session token.
  4. Issue GET /api/v2/workspaces/3871/exports/88214.
  5. Observe that the export is returned in full, with a 200 response, despite the account having no membership of workspace 3871.

Evidence

GET /api/v2/workspaces/3871/exports/88214 HTTP/1.1
Host: api.northwind-analytics.example
Authorization: Bearer eyJ0…<tenant-b analyst token, truncated>

HTTP/1.1 200 OK
Content-Type: application/json

{
  "export_id": 88214,
  "workspace_id": 3871,
  "workspace_name": "Acme Industrial (example)",
  "generated_at": "2026-03-04T09:12:44Z",
  "rows": 18422,
  "download_url": "https://exports.northwind-analytics.example/…"
}

Token and URL truncated. In the delivered report, evidence includes the full request and response pair, timestamps, and screenshots where relevant.

Remediation

Enforce workspace membership server-side on this route rather than trusting the client supplied identifier. The authorization middleware applied to the other routes in this service performs the correct check; this route bypasses it.

  1. Apply the existing workspace membership check to the export routes, and derive the permitted workspace set from the session rather than the request path.
  2. Audit every route in the export service for the same omission, since the pattern suggests the middleware is applied per route rather than by default.
  3. Change the default so authorization is required unless a route explicitly opts out, which converts this class of mistake from silent to visible.
  4. Consider non-sequential identifiers as defence in depth. This reduces enumeration but is not a substitute for the access check.
  5. Review access logs for prior exploitation, and assess notification obligations if any is found.

Retest result

Fixed and verified Membership is now enforced from the session context. Requests for a non-member workspace return 403, and the same substitution across all export routes was retested and rejected. Sequential identifiers remain in use; this was raised separately as an observation.

Note the reasoning

Severity is argued, not asserted

Every rating states why. That gives your engineers something to disagree with on evidence, rather than a number to negotiate.

Note the specificity

Remediation names the actual fix

Not "implement proper access control", but which check to apply, where, and what to change so the mistake cannot recur silently.

Note the honesty

Partial fixes stay visible

Where a fix resolves the reported path but leaves related exposure, the report says so instead of closing the item.

Want this level of detail for your product?

Start with a scope review. You will receive a written scope, an approach, and a price before committing to anything.