Supplying the Ministry of Defence? Which DCC level your contracts need, and what to do next.

Read it

Zarco / Penetration testing / Sample report

sample report: illustrative, not client data

A complete sample report

This is the report a real engagement ends with, written for a fictional company, Example Ltd. Leadership gets a plain-English summary of where the business stands; the team gets every finding, its fix and the retest result. No form, no email address.

ZarcoSample report, illustrative

Penetration test report

Security posture assessment with application and API penetration test

Example Ltd

Testing window
1 to 12 September 2026
Report issued
19 September 2026
Retest
30 September 2026
Version
v1.1, updated after retest

Example Ltd is fictional: a 60-person software company with a customer portal, a Microsoft 365 tenant and a small AWS footprint. This sample is illustrative and contains no client data.

1Section

Executive summary

The question

Where is the business exposed, and is the customer portal secure?

Overall postureAt riskGood, with two items in progress

Example Ltd asked a simple question: where is the business exposed, and is the customer portal secure? Over two weeks, our AI agents examined everything Example Ltd shows the internet, its Microsoft 365 tenant and its customer portal, and our testers confirmed twelve findings.

Four were high risk. An old admin portal was still online with outdated software. Three administrator accounts were not protected by multi-factor authentication. In the customer portal, two weaknesses combined to let one customer download another customer's exports, and sessions stayed active after a password change.

All four were fixed and verified on retest by 30 September. Two lower-risk items are in progress, and one is an accepted risk.

What's working

  • Production and staging are well separated.
  • The main website and email service are patched promptly.
  • Clear ownership: urgent findings were fixed within two days of being raised.

Priorities now

  • Finish the invitation fix on the bulk-invite path (ZP-06).
  • Move email protection from quarantine to reject (ZP-10).
  • Keep an inventory of internet-facing systems and review it quarterly.

Recommended next step

The customer portal ships weekly. Regular retesting would re-check these fixes and test new releases as they ship.

2Section

Posture at a glance

How exposed each area was when testing started, and where it stands after the retest.

Posture by area, before and after the retest
AreaBeforeAfter retestWhat changed
Internet-facing systemsAt riskGoodThe forgotten admin portal is offline. Older encryption on one site is an accepted risk.
Customer portal and APIAt riskNeeds attentionAll high-severity issues fixed. The bulk-invite path still accepts a role from the browser.
Microsoft 365At riskGoodMulti-factor authentication now covers every administrator.
Cloud storageNeeds attentionGoodPublic listing disabled and internal files moved.
Code and secretsNeeds attentionGoodThe leaked key is revoked and secret scanning is on.
Email and domainNeeds attentionNeeds attentionSpoofed email is now quarantined; blocking is planned.

3Section

Findings at a glance

  • 0Critical
  • 4High
  • 4Medium
  • 3Low
  • 1Info
Every finding, with its status after the retest
IDFindingAreaSeverityAfter retest
ZP-01Forgotten admin portal online with outdated softwareInternet-facing systemsHighFixed
ZP-02Three administrator accounts without multi-factor authenticationMicrosoft 365HighFixed
ZP-03Cross-workspace access to exportsCustomer portalHighFixed
ZP-04Sessions survive a password changeCustomer portalHighFixed
ZP-05Sequential export identifiersCustomer portalMediumFixed
ZP-06Invitation role accepted from the browserCustomer portalMediumPartially fixed
ZP-07Storage container lists file names publiclyCloud storageMediumFixed
ZP-08Email-service key in a public repository still validCode and secretsMediumFixed
ZP-09Detailed error messagesCustomer portalLowOpen
ZP-10Email domain not fully protected against spoofingEmail and domainLowPartially fixed
ZP-11Password reset links last seven daysCustomer portalLowFixed
ZP-12Older encryption protocols acceptedInternet-facing systemsInfoAccepted risk

4Section

Scope and approach

In scope

  • example.com, its subdomains and the services they expose
  • The customer portal (app.example.com) and its API (api.example.com): staging environment, three roles and two test workspaces
  • The Microsoft 365 tenant, as a read-only configuration review
  • Public code repositories and sources linked to example.com
  • Storage buckets in the AWS account that serve the website

Out of scope

  • The internal office network
  • Staff phishing and physical security
  • Denial-of-service testing
  • The third-party payment provider

Rules of engagement

  • Written authorisation from Example Ltd for every system in scope
  • Testing on weekdays, 08:00 to 18:00 UK time
  • Portal traffic limited to 4 requests per second
  • Anything that could change or delete data held for approval
  • A named stop contact on both sides

How we tested

AI agents mapped and tested the scope in parallel, with every action checked against the agreed scope before it ran. Experienced testers steered the work, confirmed every finding and rated its severity for Example Ltd's business. References: the OWASP Web Security Testing Guide and ASVS for the portal, and the CIS Microsoft 365 Foundations Benchmark for the tenant.

5Section

Attack path

Individual findings matter less than what they lead to. This path shows how two findings combined.

AP-01

A Viewer in workspace A reads workspace B's documents

  1. StartViewer role, workspace AAgreed test identity
  2. ZP-05, mediumExport IDs are sequentialValid IDs for other workspaces are predictable
  3. ZP-03, highNo ownership check on exportThe API trusts the ID it is given
  4. ObjectiveWorkspace B documentsMetadata and signed download links

Two individually moderate weaknesses combine into one high-impact path. Fixing ZP-03 closes it; fixing ZP-05 alone doesn't.

6Section

Findings in detail

ZP-01

Forgotten admin portal online with outdated software

High
Area
Internet-facing systems
Affected
admin-old.example.com
Weakness
CWE-1104: Use of unmaintained third-party components

What we found

An administration portal replaced in 2024 is still reachable from the internet. It runs a version of its software with a published high-severity vulnerability.

Why it matters

The old portal still holds customer contact records. An outsider who used the vulnerability could reach them, and nobody was watching the system.

Root cause

Decommissioning removed the portal from use but not from the internet, and there is no owned inventory of internet-facing systems.

How to fix it

Take the portal offline and remove its DNS record. Keep an inventory of internet-facing systems and review it every quarter.

ev_1a04 certificate recordev_1a05 version checkev_1a06 screenshotsRetest: Fixed. Portal offline; hostname no longer resolves.

ZP-02

Three administrator accounts without multi-factor authentication

High
Area
Microsoft 365
Affected
Conditional access policy, global administrators
Weakness
CWE-308: Use of single-factor authentication

What we found

Three of five global administrator accounts were excluded from the policy that requires multi-factor authentication.

Why it matters

A stolen or guessed password for any of these accounts would give full control of email, files and every user account.

Root cause

The accounts were excluded during a 2025 migration and never added back.

How to fix it

Require phishing-resistant multi-factor authentication for every administrator, keep two monitored emergency accounts, and review policy exclusions monthly.

ev_2b11 policy exportev_2b12 sign-in log extractRetest: Fixed. All administrators now covered; exclusions reviewed.

ZP-03

Cross-workspace access to exports

High
Area
Customer portal
Affected
GET /api/v2/exports/{exportId}
Weakness
CWE-639: Authorization bypass through user-controlled key
CVSS 4.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N

What we found

Signed in as a Viewer in one customer's workspace, we could download exports belonging to another customer.

Why it matters

Any customer could read other customers' documents, which is likely to be a reportable personal data breach.

Root cause

Workspace ownership is enforced in the interface but not in the export service.

How to fix it

Scope every export lookup to the caller's workspace in the service layer, and add a regression test that fails if it ever isn't.

Evidence: request and response

GET /api/v2/exports/10482 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOi... # viewer, workspace A

HTTP/1.1 200 OK
content-type: application/json

{ "id": 10482, "workspace": "ws_b", "name": "Q3 contracts.zip",
  "download_url": "https://files.example.com/...[redacted]" }
ev_0f3a request and responseev_0f3b screenshottrace e81fRetest: Fixed. Cross-workspace export IDs now return 404.

Other findings

In a full engagement report, each of these has the same write-up as above.

The remaining findings and how to fix them
IDFindingSeverityFix
ZP-04Sessions survive a password changeChanging a password did not sign out the account's other sessions.HighEnd every other session when a password changes, and offer users a “sign out everywhere” option.
ZP-05Sequential export identifiersExport identifiers are sequential, so valid identifiers for other workspaces are easy to predict.MediumUse random, unguessable identifiers for exports and other shared objects.
ZP-06Invitation role accepted from the browserWhen inviting a colleague, the role sent from the browser was trusted, so an Editor could invite an Admin.MediumCheck on the server that the inviter can grant the requested role, on every invitation path.
ZP-07Storage container lists file names publiclyA storage bucket for website images let anyone list its contents, including two internal price lists.MediumBlock public listing, move internal files to private storage, and serve images through the website.
ZP-08Email-service key in a public repository still validA key for the email-sending service was committed to a public repository in 2023 and still worked.MediumRevoke and replace the key, and turn on secret scanning for every repository.
ZP-09Detailed error messagesSome errors return internal details, including software versions.LowReturn generic errors to users and log the detail internally.
ZP-10Email domain not fully protected against spoofingThe domain's email policy only monitors spoofed messages rather than blocking them.LowMove the policy to quarantine, then reject, once legitimate senders are confirmed.
ZP-11Password reset links last seven daysReset links remain valid for seven days and can be used more than once.LowExpire reset links after an hour and after first use.
ZP-12Older encryption protocols acceptedThe marketing site still accepts TLS 1.0 and 1.1 alongside modern versions.InfoDisable TLS 1.0 and 1.1 at the hosting provider.

7Section

Retest record

Every finding re-tested against the deployed fix on 30 September 2026, with the original evidence as the baseline.

Retest results for every finding
IDFindingResultNote
ZP-01Forgotten admin portal online with outdated softwareFixedPortal offline; hostname no longer resolves.
ZP-02Three administrator accounts without multi-factor authenticationFixedAll administrators now covered; exclusions reviewed.
ZP-03Cross-workspace access to exportsFixedCross-workspace export IDs now return 404.
ZP-04Sessions survive a password changeFixedOriginal scenario no longer reproduces.
ZP-05Sequential export identifiersFixedOriginal scenario no longer reproduces.
ZP-06Invitation role accepted from the browserPartially fixedSingle invites fixed; the bulk-invite path still accepts a role.
ZP-07Storage container lists file names publiclyFixedOriginal scenario no longer reproduces.
ZP-08Email-service key in a public repository still validFixedOriginal scenario no longer reproduces.
ZP-09Detailed error messagesOpenScheduled by Example Ltd for the October release.
ZP-10Email domain not fully protected against spoofingPartially fixedMoved to quarantine; reject planned.
ZP-11Password reset links last seven daysFixedOriginal scenario no longer reproduces.
ZP-12Older encryption protocols acceptedAccepted riskAccepted until the site moves host in December.

AAppendix

Coverage and limitations

What was tested, partly tested or out of scope
RefAreaStatus
EXTInternet-facing discovery and testingTested
M365Microsoft 365 configurationRead-only reviewTested
WSTG-ATHNPortal authenticationTested
WSTG-ATHZPortal authorisationTested
WSTG-SESSPortal session managementTested
WSTG-INPVPortal input validationTested
WSTG-BUSLPortal business logicTested
WSTG-APITAPI testingTested
AWSCloud storage serving the websiteStorage only; no full cloud testPartial
—Internal network and phishingOut of scope
—Denial of serviceExcluded in rules of engagementOut of scope

This report describes what was tested during the testing window, against the agreed scope. It does not certify that no other vulnerabilities exist, and a clean result in an area is evidence of what was examined, not a guarantee.

Findings separate what was observed, what was suspected but not confirmed, and what was not tested and why.

BAppendix

Letter of attestation

To whom it may concern,

Zarco carried out an authorised security posture assessment with application and API penetration test for Example Ltd, under written rules of engagement agreed with Example Ltd.

Scope
example.com, app.example.com, api.example.com and the Microsoft 365 tenant
Testing window
1 to 12 September 2026
Method
Agent-assisted testing with tester validation, against OWASP WSTG and ASVS and the CIS Microsoft 365 benchmark
Results
0 critical, 4 high, 4 medium, 3 low, 1 info
Retest
All four high-severity findings fixed and verified on 30 September 2026

This is a point-in-time assessment of the agreed scope. It does not certify that the systems are free of vulnerabilities.

Lead tester, Zarco

1 October 2026

Talk to us about AI, compliance or testing.

A 30-minute call, a straight answer, and a fixed quote if there's work to do.

→Contact

Tell us what you need.

A tender deadline, an insurer's questionnaire, a system you want tested, or a job you'd like AI to take off your team's hands. We reply within one working day, UK hours.

  • A 30-minute first call, with no obligation
  • A fixed quote before any work starts
  • A UK-based team you can talk to directly