Sample deliverable

A sample security review report

This is the actual deliverable you receive from an Application Security Review, so you can read the format, the depth and the tone before you ever speak to us. Every finding is in plain language, scored by severity and fix effort, with the specific fix.

This example is fictional. Northwind Labs” is a fictional B2B SaaS, used purely to illustrate the format. The findings are realistic and representative of what we commonly see, but they are not any real company’s data. Your real report is confidential to you.

Client
Northwind Labs
Sector
B2B SaaS · team scheduling
Report date
12/08/2026
Stack
Next.jsSupabaseStripeVercel
Scope
Web application, REST API, and Supabase backend, on a staging environment mirroring production. Scope agreed in writing before any testing began.

Executive summary

We reviewed Northwind Labs’s application and the systems behind it, by hand and with automated tooling, and found 8 issues. Most serious is a single critical flaw that lets one customer read another customer’s data by changing a number in the web address. Two high issues follow: an API that can return data across every customer at once, and password-reset links that never expire.

The good news is that the most dangerous issues are also among the quickest to fix. Three of the top four are a few hours of work each. We have sequenced the remediation so the highest-risk, lowest-effort fixes come first, and every finding below carries the exact change your developers need to make.

Findings by severity

1
Critical
2
High
1
Medium
4
Low

These are the issues an external scan can’t see. The free Surface Check covers the outside; this review goes inside the application.

Detailed findings

The four most important findings from this engagement, shown in full. The real report also lists the 4 lower-severity items in the same format.

NWL-001Severity: CriticalEffort: SmallBroken access control

One customer can read another customer's data by changing an ID in the URL

The workspace dashboard trusts the numeric workspace id in the web address and never confirms, on the server, that the signed-in user actually belongs to that workspace. Any logged-in customer can change the number and load another company's schedules, members and billing contacts.

What we saw

GET /api/workspaces/4812/members returned a full member list while authenticated as a user belonging only to workspace 3307. No ownership check was applied server-side.

Why this matters: This is a direct customer-data breach that any user could trigger with a browser. It is the kind of issue that ends up in a disclosure notice and a lost enterprise deal.

The fix: Enforce ownership on every request: derive the caller's workspace from their session and reject any id they are not a member of. Back it with a Supabase Row Level Security policy so the database refuses cross-workspace reads even if a route is missed.

Estimated effort: 2 to 4 hours

NWL-002Severity: HighEffort: ModerateTenant isolation

The reporting API returns records across every workspace when a filter is left off

The analytics endpoint applies the workspace filter in the front-end, not the database query. Calling the API directly without that filter returns rows from all tenants in one response.

What we saw

POST /api/reports/export with an empty scope body returned 9,140 rows spanning 212 distinct workspace ids.

Why this matters: A single crafted request dumps the whole customer base's activity data. Unlike the dashboard, this needs no guessing of ids; it hands everything over at once.

The fix: Move tenant scoping into the query itself and default to the caller's workspace when no scope is supplied. Add Row Level Security as the backstop so an unscoped query can never cross tenants.

Estimated effort: 1 to 2 days

NWL-003Severity: HighEffort: SmallAuthentication

Password-reset links do not expire and can be reused

Reset tokens have no expiry and are not invalidated after use. A link from an old email, or one sitting in a mailbox or a proxy log, keeps working indefinitely and can be used more than once.

What we saw

A reset token issued 9 days earlier still completed a password change, and the same link worked a second time afterwards.

Why this matters: Anyone who ever sees a reset link, a forwarded email, a shared inbox, a leaked log, can take over the account at any time, long after the user has forgotten about it.

The fix: Give reset tokens a short expiry (15 to 60 minutes), make them single-use, and invalidate any outstanding tokens once one is used or a new one is requested.

Estimated effort: 3 to 5 hours

NWL-004Severity: MediumEffort: SmallPrivilege escalation

A read-only member can promote themselves to admin

The role-change endpoint checks that the caller is signed in, but not that they are already an admin. A member with the lowest permission level can call it and grant themselves administrative rights.

What we saw

PATCH /api/members/self with { role: "admin" } succeeded for a user provisioned as "viewer".

Why this matters: Any invited guest can quietly take full control of a workspace, including billing and member removal. Internal trust boundaries stop meaning anything.

The fix: Authorise the role-change endpoint on the caller's current role, not just their session, and forbid a user from elevating their own permissions.

Estimated effort: 2 to 3 hours

Remediation roadmap

A sequenced plan, highest-risk and lowest-effort first, so the team knows exactly what to do and in what order, whether we do the fixing or they do.

Do first

NWL-001, NWL-003, NWL-004

High and critical risk, each a few hours. The biggest risk reduction for the least time.

Then

NWL-002

High risk but a larger change; schedule it into the next sprint with the isolation backstop.

Backlog

The 4 low-severity items

Real, but low impact. Fix as you touch the surrounding code; none is urgent.

This is what lands in your inbox

One fixed price, a report like this in one to two weeks, and a clear plan you can act on the same day, whether your team does the fixing or we do. We reply to every enquiry within one working day.

Request a security review

Fixed £1,200 · report in 1–2 weeks · reply within one working day.