SAMPLE · PAVYZDYS · Fictional applications and findings · Real reports are confidential to the client

Sample deliverables

This is what you get.

A shortened Ship-Ready findings report for a fictional invoicing SaaS built by an outsourced team, and a complete sample Release Readiness Attestation. A real report has the same structure, with every finding written out in full.

Part 1

Findings report

MRE LABS · SHIP-READY SECURITY REVIEW · FINDINGS REPORTCONFIDENTIAL · SAMPLE

1. Summary

Product
Acme Invoicing web application and API (fictional)
Client
Client name redacted
Version
Commit 4f2a9c1, main branch
Review period
14–18 September 2026 (5 business days)
Report date
18 September 2026
Status statement
(2) At the issue date, no Critical findings remained open within the stated scope. 2 High severity findings remained open; they are listed in the Findings Report with remediation scheduled by 18 October 2026. This attestation will be reissued after retest.

Acme Invoicing is in better shape than most outsourced builds of its age. Authentication is sound, there are no secrets in the git history, and the infrastructure is simple. One Critical issue let any logged-in customer read every other customer's invoices. It was fixed during the review and verified on Day 5. Two High issues remain open, both small fixes. They are why status statement (2) applies rather than (1), and the attestation is reissued once their retest passes.

1Critical · fixed
2High · open
4Medium
3Low

2. Scope and method

In scope
One repository (TypeScript API, React frontend), about 38k lines of code, full git history; staging environment with two test organisations; deployment configuration and CI pipeline.
Out of scope
Production systems, the mobile app, third-party services beyond how they are integrated.
Method
Static analysis, dependency audit and secrets scan of the full history; manual review of the ten review areas; each Critical and High finding confirmed with a single, non-destructive proof-of-concept request on staging, using test data. Ship-Ready includes no dynamic testing beyond that.

3. Findings overview

IDSeverityFindingAreaStatus
C-01 CRITICAL Any customer can read any other customer's invoices Authorization & tenant isolation Fixed on Day 4, verified Day 5
H-01 HIGH Payment webhook accepts unsigned requests API & business logic Open, due 18 October 2026
H-02 HIGH Password reset tokens never expire and can be reused Authentication & sessions Open, due 18 October 2026
M-01 MEDIUM Invoice amounts validated in the UI only; API accepts negative values Input handling Open, 30 days
M-02 MEDIUM Former contractor's deploy key still active Operational readiness Open, 30 days
M-03 MEDIUM Unhandled errors return stack traces and SQL to the browser Secrets & configuration Backlog
M-04 MEDIUM PDF rendering dependency two major versions behind, with published advisories Dependencies & supply chain Backlog
L-01 LOW No rate limit on login and password reset Authentication & sessions Backlog
L-02 LOW No Content-Security-Policy or Referrer-Policy header Secrets & configuration Backlog
L-03 LOW Sessions last 30 days with no idle timeout Authentication & sessions Backlog

4. Selected findings in detail

Three of the ten findings are shown in full: the Critical, and the two open Highs behind status statement (2). Every finding in a real report has the same five parts.

CRITICALC-01 · Any customer can read any other customer's invoices

What's wrong

The invoice endpoint loads an invoice by its ID and returns it without checking that it belongs to the caller's organisation. Invoice IDs are sequential, so they are easy to enumerate.

Evidence

// src/api/invoices/[id].ts:14
export async function getInvoice(req: Request, res: Response) {
  const invoice = await db.invoice.findUnique({
    where: { id: req.params.id },          // <- no organisation filter
  });
  if (!invoice) return res.status(404).end();
  return res.json(invoice);
}

On staging, a user in test organisation B retrieved invoice 10412, which belongs to organisation A, with a single request. The same pattern appears in 4 of the 23 tenant-scoped endpoints (listed in the appendix).

Impact

Any paying customer could download every other customer's invoices: names, addresses, amounts and bank details. That is a reportable personal-data breach under GDPR.

Fix

const invoice = await db.invoice.findFirst({
  where: { id: req.params.id, orgId: req.user.orgId },
});

Then move tenant scoping into one shared data-access helper so a new endpoint can't forget it, and add a test that calls each endpoint as the wrong tenant. Effort: half a day for the four endpoints, one day for the helper and tests.

Status

Fixed in commit 7c1e0b3 on Day 4. Verified on staging on Day 5: all 23 endpoints return 404 for another organisation's records.

HIGHH-01 · Payment webhook accepts unsigned requests

What's wrong

The payment provider signs every webhook. The handler never checks that signature, so it trusts any request sent to the URL.

Evidence

// src/webhooks/payments.ts:9
app.post('/webhooks/payments', express.json(), async (req, res) => {
  const event = req.body;                  // <- signature header never checked
  if (event.type === 'invoice.paid') {
    await markPaid(event.data.object.metadata.invoiceId);
  }
  res.sendStatus(200);
});

Impact

Anyone who knows the webhook URL, which appears in the frontend bundle's error-reporting config, can mark any invoice as paid and unlock paid features without paying. The preconditions are knowing the URL and an invoice ID, which is why this is High rather than Critical.

Fix

Verify the signature using the raw request body and the signing secret, using the provider's SDK. Reject events older than five minutes, and store processed event IDs so a replayed event is ignored. Effort: about two hours.

Status

Open. Agreed fix date 18 October 2026; included in the re-test.

HIGHH-02 · Password reset tokens never expire and can be reused

What's wrong

A password reset link stays valid forever and keeps working after it has been used. The token is stored in plain text, and changing the password doesn't end existing sessions.

Evidence

// src/auth/reset.ts:22
export async function requestReset(email: string) {
  const user = await db.user.findUnique({ where: { email } });
  if (!user) return;
  const token = crypto.randomBytes(32).toString('hex');
  await db.user.update({
    where: { id: user.id },
    data: { resetToken: token },           // <- stored in plain text, no expiry
  });
  await mailer.sendPasswordReset(user.email, token);
}

// src/auth/reset.ts:41
export async function resetPassword(token: string, password: string) {
  const user = await db.user.findFirst({ where: { resetToken: token } });
  if (!user) throw new BadRequestError();
  await db.user.update({
    where: { id: user.id },
    data: { passwordHash: await hash(password) },  // <- token not cleared, sessions kept
  });
}

On staging, a reset link requested on Day 1 still worked on Day 4. The same link worked a second time after the password had already been changed, and the session from before the reset stayed logged in throughout.

Impact

Anyone who ever gets hold of an old reset email can take over that account at any time: a forwarded or shared mailbox, a former employee, or a leak of the email provider's logs. The real user changing their password doesn't lock them out, and nothing alerts the user. The precondition is access to a past reset email, which is why this is High rather than Critical. Because the tokens are stored in plain text, a database leak would expose every pending reset as well.

Fix

Store only a hash of the token, with an expiry of 30 to 60 minutes. Clear it the moment it's used, and invalidate any other outstanding tokens for that user. End all existing sessions when the password changes, and email the user to say it was changed. Add tests for an expired token, a reused token and session invalidation. Effort: half a day including tests.

Status

Open. Agreed fix date 18 October 2026; included in the re-test.

5. Fix list

Before go-live

  • C-01 (done)

Within 30 days

  • H-01, H-02: retested before the attestation is reissued
  • M-01, M-02

Backlog

  • M-03, M-04
  • L-01, L-02, L-03

6. Compliance signals

What these findings mean for the frameworks your customers and auditors ask about. These are signals, not an assessment.

FrameworkSignalRelated
GDPR Art. 32–33Personal data was exposed across tenants until the fix. Check the access logs for signs it was exploited before then, to decide whether the 72-hour breach notification applies.C-01
NIS2 Art. 21If you're in scope: access control, supplier access and vulnerability handling need documented controls. A former contractor still had access, and dependencies aren't tracked.M-02, M-04
Cyber Resilience ActIf you sell a product with digital elements in the EU: there's no SBOM, so nobody can tell when a dependency needs a security update.M-04
SOC 2 · ISO 27001The questions customers ask most often about logical access and account recovery would currently be answered "no" or "partly".C-01, H-02, M-02

Turning these signals into the evidence an auditor or a customer's security questionnaire accepts is a separate engagement: the Compliance Readiness Pack.

A real report continues with every remaining finding in full and an appendix of affected files and tool output.

Part 2

Release Readiness Attestation

One signed, verifiable page: the document you forward to a customer's security team, an investor or an insurer. This sample is for a different fictional system, whose High findings were fixed and retested, so it carries status statement (1).

SAMPLE · PAVYZDYS: fictitious system and client, for illustration

MRE Labs UAB "Megabonus" company code 300046310 Not VAT-registered Gyrio g. 5, LT-47200 Kaunas, Lithuania mrelabs.dev

Release Readiness Attestation

Attestation ID
MRE-ATT-2026-000
Date of issue
2026-11-03

Issued to

UAB Pavyzdys, attn. Rūta Pavyzdienė, CEO

System reviewed

Vėjas Rezervacijų sistema v2.3.1 — vejas/booking-api, vejas/booking-web at commit a1b2c3d — staging

Scope

In scope
booking API (NestJS), web client (Next.js), PostgreSQL schema and migrations, staging configuration
Out of scope
production environment, payment provider integration, mobile app
Review package
Ship-Ready Review
Review period
2026-10-20 – 2026-10-24 · Effort: 5 person-days
Retest
2026-11-03 (Critical and High findings only)

Method

Automated static analysis, dependency and secrets scanning (Semgrep 1.x, Trivy 0.x, gitleaks 8.x); manual review of authentication, authorization, tenant isolation, input handling, data protection and configuration; infrastructure and CI/CD configuration review; Critical and High findings confirmed by single proof-of-concept requests on staging. Methodology reference: OWASP Web Security Testing Guide v4.2 / OWASP ASVS 4.0 level 2; MRE Labs review checklist v1. Full findings: Findings Report v1.0 dated 2026-10-24.

Findings at issue date

SeverityFoundRemediated and retestedOpen
Critical000
High000
Medium312
Low523

Status statement

(1) At the retest date stated above, no Critical or High severity findings remained open within the stated scope. Medium and Low findings are documented in the Findings Report with a remediation plan.

How this document may be used

This attestation records that an independent review of the named system was carried out with the method and scope above, and the state of its findings at the dates stated. The client may provide it to customers, partners, insurers, investors and auditors for information, and may file it as evidence of an independent assessment under its own supplier-monitoring procedures (for Lithuanian cybersecurity entities: Government Resolution No. 818, points 34.4, 35 and 38). It is not a certification of compliance with any law or standard and does not replace a statutory audit.

Limitations

This document reflects the named version at the review and retest dates and the scope stated. It does not cover changes made afterwards, components outside the scope, or weaknesses not detectable with the method and time applied. It is a professional opinion on the findings of a time-boxed review, not a warranty or guarantee of security. Liability is as agreed in the engagement contract.

Reviewer

Zilvinas Binisevicius

Zilvinas Binisevicius, lead reviewer
[credential pending] · 30 years in software engineering and operations
UAB "Megabonus", company code 300046310, Not VAT-registered
Professional indemnity insurance: [policy pending]

Verify

mrelabs.dev/verify/MRE-ATT-2026-000 · PDF SHA-256: 972b896338447f12a4f8da52d65ea247fd3c6e355cfcbdf2f2617f326f7268e7

Book a review

Want this for your application?

Book a 20-minute scoping call. Tell me what the product does, who built it, roughly how big it is and when you need the attestation, and I'll tell you which package fits and when I can start.