Powered by BrokenIntent
Confidential · Penetration Test Report

Web Application &
API Penetration Test

Grey-box assessment of the Acme web application, REST API, and Supabase backend, validated by hand by senior security engineers.

OWASP Top 10 OWASP API Top 10 PTES NIST SP 800-115
Prepared for
Acme, Inc.
Engagement
VS-2026-0617
Testing window
9–11 Jun 2026
Report version
v1.1 - Final
hello@vibesecurely.com · vibesecurely.com
Confidential · VS-2026-0617
00

Document control

This report contains confidential security findings about Acme systems. Distribution is restricted to the named recipients below. Handle in accordance with your internal data-classification policy.

Document properties

TitleWeb Application & API Penetration Test - Acme, Inc.
ClassificationConfidential
Engagement referenceVS-2026-0617
Assessment typeGrey-box penetration test (unauthenticated + authenticated)
Testing window9 June 2026 – 11 June 2026
Report date13 June 2026
Retest date20 June 2026

Prepared by - VibeSecurely

Lead engineerR. Mehta - OSCP, OSWE
EngineerD. Alvarez - OSEP, eWPTX
QA / reviewerS. Okafor - OSCP, CRTP
Delivered withBrokenIntent (testing partner)

Prepared for - Acme

Primary contactJ. Whitfield - VP Engineering
Technical contactP. Nguyen - Security Lead
AuthorizationSigned SOW & scope - 06 Jun 2026
DistributionRestricted - named recipients only

Version history

VersionDateAuthorNotes
v0.111 Jun 2026R. MehtaInternal draft - findings complete
v1.013 Jun 2026S. OkaforQA review, delivered to client
v1.120 Jun 2026R. MehtaRetest results & attestation appended
Confidentiality notice

This document describes live security weaknesses and must not be redistributed, in whole or in part, without written authorization. If you received this in error, delete it and notify hello@vibesecurely.com.

ConfidentialVibeSecurely · VS-2026-0617Page 2
Confidential · VS-2026-0617
-

Contents

1 · Executive summary4
2 · Risk posture & findings overview5
3 · Scope, approach & methodology6
4 · Risk-rating methodology (CVSS v3.1)7
5 · Findings summary table8
6 · Detailed findings9
6.1 · VS-01 - Read/modify any user's orders (IDOR)9
6.2 · VS-02 - Account takeover via email change10
6.3 · VS-03 - Unrestricted file upload → RCE11
6.4 · VS-04 - Blind SQL injection in search12
6.5 · VS-05 - Supabase RLS disabled (public read)13
6.6 · Remaining findings (VS-06 – VS-14)14
7 · Strategic recommendations15
8 · Retest results & attestation16
9 · Appendix - tooling & glossary17
How to read this report

Section 1 is written for leadership - no tooling, just business risk and the bottom line. Sections 5–6 are written for engineers - every finding has reproduction steps, proof-of-concept, and a concrete fix. Section 8 is for your buyer's security team - retest verification and a signed attestation. Hand the whole document over as-is.

ConfidentialVibeSecurely · VS-2026-0617Page 3
Confidential · VS-2026-0617
01

Executive summary

Acme engaged VibeSecurely to perform a grey-box penetration test of its web application, REST API, and Supabase backend ahead of an enterprise customer's security review. Testing ran from 9–11 June 2026 against a staging environment that mirrors production. The objective: determine whether an external attacker, or a low-privileged authenticated user, could read other customers' data, take over accounts, or execute code.

The product is well-built in places, but shipped three critical and five high-severity flaws that - chained - allow full compromise of customer data. The most serious (VS-01) lets any authenticated user read and modify other users' orders by changing one numeric ID. Combined with the unauthenticated email change (VS-02) and the file-upload flaw (VS-03), an attacker could take over accounts and execute code in the application's origin. We confirmed each with proof-of-concept and stopped short of bulk extraction by agreement.

Bottom line

An attacker with a standard account could reach other customers' data within hours - no special tooling required. Every fix is well-understood and scoped to under two engineering weeks. Remediate VS-01, VS-02, and VS-03 before the next release; none require an architectural change.

What we found

What is working well

Path forward

Fix the access-control findings (VS-01, VS-05, VS-07) as a single workstream - they share a root cause and a shared fix: centralized, server-side authorization. Request a retest as remediation lands; VibeSecurely re-validates each fix and updates this report's attestation.

ConfidentialVibeSecurely · VS-2026-0617Page 4
Confidential · VS-2026-0617
02

Risk posture & findings overview

3
Critical
5
High
3
Medium
3
Low

Findings by severity

14 findings total
Critical · 3 High · 5 Medium · 3 Low · 3

Risk by category (OWASP)

CategoryFindingsHighest severityResidual after fix
A01 - Broken Access Control4CriticalLow
A07 - Identification & Auth Failures4CriticalLow
A03 - Injection1HighLow
A04 - Insecure Design2CriticalLow
A05 - Security Misconfiguration3MediumLow

Attack narrative - how the findings chain

1. Foothold. Register a standard user account (self-service, no verification).

2. Horizontal access. Use the IDOR on /api/orders/{id} (VS-01) to read other users' orders and PII.

3. Takeover. Change a victim's email with no re-auth (VS-02), then password-reset into their account.

4. Code execution. Upload an HTML/JS file (VS-03) served from the application origin to run code and harvest sessions at scale.

Each step was demonstrated in an isolated staging environment with explicit authorization. No production data was accessed; no records were exfiltrated in bulk.

ConfidentialVibeSecurely · VS-2026-0617Page 5
Confidential · VS-2026-0617
03

Scope, approach & methodology

In scope

AssetTypeEnvironmentAccess level
app.acme.ioWeb applicationStagingUnauthenticated + authenticated
app.acme.io/apiREST API (28 endpoints)StagingUnauthenticated + authenticated
Supabase project (Postgres + Storage)Backend-as-a-serviceStagingAnon key + config review

Out of scope

Rules of engagement

Methodology

VibeSecurely combines broad automated attack-surface mapping with hands-on testing by senior security engineers, who manually validate, exploit, and rule out false positives. Every finding in this report was reproduced by hand. Our process aligns to:

Standards & frameworks
  • OWASP Web Security Testing Guide (WSTG) 4.2
  • OWASP Top 10 (2021) & API Security Top 10 (2023)
  • PTES - Penetration Testing Execution Standard
  • NIST SP 800-115
Phases
  • 1 · Scoping & reconnaissance
  • 2 · Attack-surface mapping & enumeration
  • 3 · Manual vulnerability discovery
  • 4 · Exploitation & impact validation
  • 5 · Reporting, walkthrough & retest
Why automated scanning isn't enough

Automated scanners reliably miss business-logic and access-control flaws - exactly the issues that did the most damage here (VS-01, VS-02, VS-07). Broad tooling provides coverage across the API quickly; experienced testers provide the judgment to chain findings into real attacks and discard noise. Three of the top findings would not have been caught by tooling alone.

ConfidentialVibeSecurely · VS-2026-0617Page 6
Confidential · VS-2026-0617
04

Risk-rating methodology

Each finding is scored with CVSS v3.1 for base technical severity, then adjusted for Acme's business context (data sensitivity, exposure, exploit complexity) to produce the final risk rating used throughout this report.

SeverityCVSSMeaningExpected response
Critical9.0–10.0Direct path to mass data loss or full compromise; trivial to exploit.Fix immediately.
High7.0–8.9Serious impact to confidentiality, integrity, or availability.Fix in current sprint.
Medium4.0–6.9Meaningful risk, usually requiring a precondition or chaining.Next release cycle.
Low0.1–3.9Limited impact; hardening / defense-in-depth.As capacity allows.

How to read a CVSS vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
AV - Attack VectorN = Network (exploitable remotely)
AC - Attack ComplexityL = Low (no special conditions)
PR - Privileges RequiredL = Low (any authenticated user)
UI - User InteractionN = None (no victim action needed)
S - ScopeU = Unchanged
C / I / A - ImpactConfidentiality / Integrity / Availability - None, Low, or High
ConfidentialVibeSecurely · VS-2026-0617Page 7
Confidential · VS-2026-0617
05

Findings summary table

All 14 findings, ordered by severity. Retest status reflects the 20 June 2026 re-validation.

IDFindingOWASPSeverityCVSSRetest
VS-01Read/modify any user's orders (IDOR)A01Critical9.1Fixed ✓
VS-02Account takeover via unauthenticated email changeA07Critical9.3Fixed ✓
VS-03Unrestricted file upload → remote code executionA04Critical9.6Fixed ✓
VS-04Blind SQL injection in product searchA03High8.2Fixed ✓
VS-05Supabase RLS disabled - public table readA01High8.1Fixed ✓
VS-06No rate limiting on login (credential stuffing)A07High7.5Fixed ✓
VS-07Price tampering via client-controlled cartA04High7.4Fixed ✓
VS-08Broken object-level auth on user profiles (BOLA)A01High7.1Fixed ✓
VS-09Wildcard CORS with credentialsA05Medium5.3Fixed ✓
VS-10Stripe key exposed in client bundleA05Medium5.1Fixed ✓
VS-11Session cookie missing Secure / SameSiteA05Medium4.6Fixed ✓
VS-12Verbose API error messages leak stack tracesA05Low3.4Fixed ✓
VS-13Username enumeration on signupA07Low3.1Accepted
VS-14Weak password policy (8 chars, no breach check)A07Low2.8Accepted
12
Remediated & retested
2
Risk accepted
0
Open / unresolved
ConfidentialVibeSecurely · VS-2026-0617Page 8
Confidential · VS-2026-0617
06

Detailed findings

VS-01 · A01 Broken Access Control · CWE-639
Read/modify any user's orders (IDOR)
Critical
CVSS 9.1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Summary

GET /api/orders/{id} returns an order based solely on the numeric id. The server checks that the caller is authenticated, but never that the order belongs to the caller. Any authenticated user can read - and via PUT, modify - every other user's order by incrementing the ID. IDs are sequential.

Affected asset

app.acme.io/api/orders/{id} (GET, PUT, DELETE)

Steps to reproduce
  1. Register an account; note your own order ID (e.g. 1042) and capture your bearer token.
  2. Request a different ID. The server returns the full order despite no ownership relationship.
  3. Repeat across a range to confirm sequential, enumerable access.
Proof of concept
# Authenticated as user 1042, request order 1041
$ curl -s https://app.acme.io/api/orders/1041 \
     -H "Authorization: Bearer eyJhbGciOi...<user-1042-token>"

{
  "id": 1041,
  "email": "victim@acme.io",
  "total": "$240.00",
  "address": "21 Pine St, Austin TX",
  "card_last4": "4242"
}   # 200 OK - not the caller's order
Business impact

Full read/write access to every customer's orders and PII. A single script enumerates the entire order table in minutes - a reportable data breach and an instant fail of any customer's security review.

Remediation

Enforce object-level authorization on every record fetch: verify order.user_id === session.user_id (or use Postgres row-level security) before returning data. Never treat a client-supplied ID as proof of ownership. Apply the same check to PUT/DELETE.

Retest

Fixed ✓ - ownership now enforced in middleware; cross-user access returns 403. Re-validated 20 Jun 2026.

ConfidentialVibeSecurely · VS-2026-0617Page 9
Confidential · VS-2026-0617
VS-02 · A07 Identification & Auth Failures · CWE-620
Account takeover via unauthenticated email change
Critical
CVSS 9.3
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Summary

POST /api/account/email updates the account email with no re-authentication and no confirmation to the old address. With a hijacked session - or via CSRF - an attacker changes a victim's email, then triggers a password reset to fully take over the account.

Proof of concept
# Change the logged-in user's email - no password required
$ curl -s -X POST https://app.acme.io/api/account/email \
     -H "Authorization: Bearer <session>" \
     -d '{"email":"attacker@evil.com"}'

{ "ok": true }   # no confirmation to the old address
Business impact

Any session compromise (XSS, a borrowed device, a leaked token) escalates to permanent account takeover, including any payment methods and data on the account.

Remediation

Require the current password (or a fresh re-auth) to change email; send a confirmation link to the old address; invalidate active sessions on change. Add CSRF protection to all state-changing routes.

Retest

Fixed ✓ - re-auth + old-address confirmation now required. Re-validated 20 Jun 2026.

ConfidentialVibeSecurely · VS-2026-0617Page 10
Confidential · VS-2026-0617
VS-03 · A04 Insecure Design · CWE-434
Unrestricted file upload → remote code execution
Critical
CVSS 9.6
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Summary

The avatar upload (POST /api/upload) accepts any file type and stores it under the web root with its original name. Uploading an HTML/JS file and requesting it back executes attacker code in the application's own origin - stealing sessions and pivoting.

Proof of concept
# Upload an HTML payload as an "avatar"
$ curl -s -X POST https://app.acme.io/api/upload \
     -H "Authorization: Bearer <session>" \
     -F "file=@xss.html;type=text/html"

{ "url": "/uploads/xss.html" }
# → served executable at https://app.acme.io/uploads/xss.html
Business impact

Same-origin code execution: an attacker can steal any visiting user's session, deface the application, or stage further attacks. Combined with VS-02, this is full multi-account compromise.

Remediation

Allowlist MIME types and extensions, generate random server-side filenames, store uploads off-origin (e.g. Supabase Storage / object storage) and serve with Content-Disposition: attachment. Never serve user uploads as executable content from the application origin.

Retest

Fixed ✓ - uploads moved to object storage with type allowlist + random names. Re-validated 20 Jun 2026.

ConfidentialVibeSecurely · VS-2026-0617Page 11
Confidential · VS-2026-0617
VS-04 · A03 Injection · CWE-89
Blind SQL injection in product search
High
CVSS 8.2
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Summary

The q parameter on GET /api/search is concatenated directly into a SQL query. A time-based payload confirms injection - opening the door to a full database read, including users and session tokens.

Proof of concept
# Time-based blind confirmation - response delays ~5s
$ curl -s -G https://app.acme.io/api/search \
     --data-urlencode "q=' OR SLEEP(5)-- -"

# 200 OK after ~5.0s → injectable
Business impact

An unauthenticated attacker can read arbitrary database contents over time, including credentials and PII - a direct path to a full data breach.

Remediation

Use parameterized queries / prepared statements (or the ORM query builder). Never build SQL by string concatenation. Add a WAF rule as defense-in-depth.

Retest

Fixed ✓ - query rewritten with bound parameters. Re-validated 20 Jun 2026.

ConfidentialVibeSecurely · VS-2026-0617Page 12
Confidential · VS-2026-0617
VS-05 · A01 Broken Access Control · CWE-284
Supabase RLS disabled - public table read
High
CVSS 8.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
Summary

The public.profiles table was created with Row-Level Security disabled. Because the Supabase anon key is - by design - shipped to the browser, anyone can query the table directly and read every user's row, bypassing the application entirely.

Proof of concept
# Query Supabase REST directly with the public anon key
$ curl -s "https://<proj>.supabase.co/rest/v1/profiles?select=*" \
     -H "apikey: <public-anon-key>"

[ { "id": 1, "email": "a@acme.io", "phone": "+1…" }, … ]
# every row returned - RLS off
Business impact

The entire user table is readable by anyone who views the site's JavaScript - a full disclosure of user records. Misconfigured row-level security is among the most common and most damaging issues in Supabase-backed applications.

Remediation

Enable RLS on every table (alter table … enable row level security) and add explicit policies (e.g. user_id = auth.uid()). Audit all tables - RLS is off by default on new tables.

Retest

Fixed ✓ - RLS enabled with per-user policies across all tables. Re-validated 20 Jun 2026.

ConfidentialVibeSecurely · VS-2026-0617Page 13
Confidential · VS-2026-0617
6.6

Remaining findings (VS-06 – VS-14)

High, medium, and low findings in brief. Each was reproduced and retested; full reproduction steps are available on request.

VS-06 · A07 · CWE-307 No rate limiting on login
High · 7.5

Login has no throttling, lockout, or CAPTCHA - thousands of credential-stuffing attempts per minute succeed silently.

Fix: per-IP + per-account rate limiting with backoff, lockout after repeated failures, offer MFA.

VS-07 · A04 · CWE-602 Price tampering via client-controlled cart
High · 7.4

Checkout trusts client-supplied price and quantity; a negative quantity or altered price yields a $0 (or credited) order.

Fix: compute totals server-side from trusted catalog data; reject non-positive quantities; never accept price from the client.

VS-08 · A01 · CWE-639 BOLA on user profiles
High · 7.1

GET /api/users/{id} returns any user's full profile and PII by iterating the ID - same root cause as VS-01, second endpoint.

Fix: centralized authorization middleware enforcing ownership/role on every object access.

VS-09 · A05 Wildcard CORS with credentials
Medium · 5.3

Access-Control-Allow-Origin: * with credentials lets any site make authenticated requests on a victim's behalf.

Fix: reflect only an allowlist of trusted origins; never pair * with credentials.

VS-10 · A05 · CWE-312 Stripe key exposed in client bundle
Medium · 5.1

A Stripe restricted key was hardcoded in the front-end JavaScript, readable by anyone who opens DevTools.

Fix: move the key server-side; rotate the exposed key; use only publishable keys client-side.

VS-11 (session cookie flags · 4.6), VS-12 (verbose errors · 3.4), VS-13 (username enumeration · 3.1), and VS-14 (weak password policy · 2.8) are detailed in the engagement appendix. VS-13 and VS-14 were formally risk-accepted with compensating controls.

ConfidentialVibeSecurely · VS-2026-0617Page 14
Confidential · VS-2026-0617
07

Strategic recommendations

Beyond the individual fixes, three changes would prevent this whole class of issue from recurring as the application grows.

1 · Authorize server-side, centrally

Most findings share one root cause: the application trusts client-supplied IDs and roles. Add a single authorization layer that checks ownership/role on every object access - don't patch endpoints one at a time. Enable Supabase RLS on every table as a backstop.

2 · Never trust client input for security or money

Prices, quantities, file types, and SQL inputs must be validated and computed on the server. Treat everything from the browser as hostile.

3 · Add a security checklist to your release flow

These patterns are easy to reintroduce as the codebase grows. A lightweight pre-release checklist (authorization, RLS, secrets, rate limits) plus a periodic penetration test keeps new code from reopening fixed holes.

ConfidentialVibeSecurely · VS-2026-0617Page 15
Confidential · VS-2026-0617
08

Retest results & attestation

On 20 June 2026, VibeSecurely re-tested all findings after Acme's remediation. All 3 critical and all 5 high findings are fixed and verified. Twelve of fourteen findings are remediated; two low-severity findings were formally risk-accepted with documented compensating controls.

12
Fixed & verified
2
Risk accepted
0
Open
Attestation

VibeSecurely confirms that, as of 20 June 2026, the critical and high-severity vulnerabilities identified in this assessment of the Acme application have been remediated and re-validated. No critical or high-severity issues remain open. This attestation may be shared with prospective customers and their security teams.

Signed - R. Mehta (OSCP, OSWE), Lead Engineer, VibeSecurely · in partnership with BrokenIntent.

ConfidentialVibeSecurely · VS-2026-0617Page 16
Confidential · VS-2026-0617
09

Appendix - tooling & glossary

Representative tooling

Manual testing with Burp Suite Professional and custom scripts; automated attack-surface mapping; Supabase/Postgres configuration review. All exploitation was performed by hand and confirmed.

Glossary

IDOR / BOLAAccessing another user's object by changing its identifier, with no ownership check.
RLSRow-Level Security - Postgres/Supabase policies that restrict which rows a query can return.
SQLiSQL injection - attacker-controlled input altering a database query.
CVSSCommon Vulnerability Scoring System - a 0–10 technical severity score.
RCERemote Code Execution - running attacker code on the server or in the application origin.

This is a sample report prepared for an illustrative target (app.acme.io) to demonstrate the VibeSecurely deliverable.
VibeSecurely · hello@vibesecurely.com · vibesecurely.com · powered by BrokenIntent

ConfidentialVibeSecurely · VS-2026-0617Page 17