TrojanStrike

Classified After-Action Report

acme-store.com

VERDICT: BREACHED
TIER: STRIKE QUEUED: 2026-08-14 09:30:00 UTC STARTED: 2026-08-14 09:31:12 UTC FINISHED: 2026-08-14 09:47:03 UTC DURATION: 15m 51s

Executive Summary

The target exhibits one or more critical/high-severity weaknesses that an attacker could exploit to compromise confidentiality, integrity, or availability. Immediate remediation is required.

SeverityCount
CRITICAL1
HIGH1
MEDIUM1
LOW2
INFO1
TOTAL6

Since Last Scan

since last scan: 1 new, 5 persisting, 1 fixed

NEW: Cross-user order receipt access
FIXED: Directory listing exposed at /backups/

Coverage

GRADE: GOOD REQUESTS: 2874/3000 CHECKS: 14 ran · 1 nothing to test · 0 skipped
CheckOutcomeDetailRequests
crawlRAN41 pages, 12 forms, 9 API endpoints mapped320
tlsRANTLS 1.3, valid certificate2
cookiesRAN3 cookie(s) across 42 URL(s) — 0 finding(s)64
headersRAN2 finding(s)3
js-cveRAN0 finding(s) — 14 script(s) assessed210
exposed-filesRANbaseline 404/18 chars, 39 probes → 0 finding(s)96
tech-cveRAN1 finding(s)41
dir-probeRANbaseline 404/18 chars, 46 paths → 0 finding(s)128
error-leakRANprobed 11 URL(s) → 0 finding(s)248
reflected-xssRAN1 finding(s)96
dom-xssRAN0 finding(s) — 5 page(s) browser-probed384
sqliRAN1 finding(s)412
idorRAN1 finding(s)118
api-fuzzRAN0 finding(s) — 9 endpoint(s) fuzzed752
cmdiNOTHING_TO_TEST0 injection points inside scope0

Remediation Priority

SeverityFindingUrgency
HIGH Cross-user order receipt access Fix within 24–48 hours
CRITICAL SQL injection in product search Fix immediately — active exploitation likely
MEDIUM Reflected XSS in search results page Fix before next release
LOW Missing Cross-Origin-Resource-Policy header on static assets Address in next sprint
INFO Technology detected: Next.js 15.1.2 Informational
LOW X-Powered-By header discloses framework Address in next sprint

Attack Narrative

TimePhaseEvent
2026-08-14 09:31:12 UTCSYSTEMstrike accepted — budget 3000 requests at 5 rps, kill switch armed
2026-08-14 09:33:40 UTCRECONcrawl complete: 41 pages, 12 forms, 9 API endpoints mapped
2026-08-14 09:34:02 UTCRECONtech-cve: GET https://acme-store.com/ → 200 — Next.js 15.1.2 fingerprinted
2026-08-14 09:38:15 UTCPROBEsqli: error differential on /search?q= — 1 injectable candidate
2026-08-14 09:41:27 UTCBREACHsqli: UNION context confirmed, 7 columns — banner extracted read-only
2026-08-14 09:44:51 UTCBREACHidor: /api/orders/1042 returned a foreign owner reference — BOLA confirmed
2026-08-14 09:47:03 UTCVERDICTBREACHED — 6 finding(s): 1 CRITICAL, 1 HIGH, 1 MEDIUM, 2 LOW, 1 INFO
2026-08-14 09:47:03 UTCVERDICTcoverage GOOD — 14 ran, 1 nothing-to-test, 0 skipped; 2874/3000 requests
2026-08-14 09:47:03 UTCVERDICTsince last scan: 1 new, 5 persisting, 1 fixed

Findings

CRITICAL
Fix immediately — active exploitation likely

SQL injection in product search

#:1
Category:sqli
CWE:CWE-89
CVSS:9.1
Confidence:98%
Status:OPEN
Diff:PERSISTING
URL: https://acme-store.com/search
Field: q
Snippet
GET /search?q=gift' UNION SELECT NULL,version()-- -
UNION context confirmed (7 columns); database banner extracted read-only: PostgreSQL 15.4 on x86_64-pc-linux-gnu.
curl -H 'Accept: text/html' 'https://acme-store.com/search?q=gift%27%20UNION%20SELECT%20NULL%2Cversion%28%29--%20-'
The search endpoint concatenates the q parameter directly into a SQL query, allowing an attacker to read arbitrary tables — including customer credentials and order history.
Use parameterized queries for all database access.
Replace string concatenation with bound parameters at every call site. The query builder should never see raw user input — validate and type-check q before it reaches the data layer.
const rows = await db.query(`SELECT * FROM products WHERE name ILIKE '%${q}%'`);
const rows = await db.query('SELECT * FROM products WHERE name ILIKE $1', [`%${q}%`]);
  • https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
  • https://cwe.mitre.org/data/definitions/89.html
Tags: OWASP ASVS V5, PCI-DSS 6.5.1
HIGH
Fix within 24–48 hours

Cross-user order receipt access

#:2
Category:idor
CWE:CWE-639
CVSS:8.2
Confidence:97%
Status:OPEN
Diff:NEW
URL: https://acme-store.com/api/orders/1042
GET /api/orders/1042 → 200 — authenticated as user A (id 317), response contains user B's order record (owner id 219): customer name, delivery address, and itemized receipt.
curl -H 'Accept: application/json' 'https://acme-store.com/api/orders/1042'
Order receipts are fetched by sequential id with no ownership check. Any authenticated user can read any other customer's order record by incrementing the id.
Enforce object-level authorization on every record fetch (CWE-639).
Scope every object lookup to the authenticated principal: fetch the order WHERE id = $1 AND user_id = $2, and return 404 (not 403) when no row matches, so ids cannot be enumerated. Apply the same pattern to every id-addressable resource.
  • https://owasp.org/www-project-api-security/ — API1:2023 Broken Object Level Authorization
  • https://cwe.mitre.org/data/definitions/639.html
Tags: OWASP API Top 10, PCI-DSS 7.1
MEDIUM
Fix before next release

Reflected XSS in search results page

#:3
Category:reflected-xss
CWE:CWE-79
CVSS:6.1
Confidence:90%
Status:OPEN
Diff:PERSISTING
URL: https://acme-store.com/search
Field: q
Markup canary ts9f3k2 reflected unescaped into the results page HTML — string-delimiter breakout confirmed content-type-aware.
curl -H 'Accept: text/html' 'https://acme-store.com/search?q=ts9f3k2%22%3E%3Csvg%20id%3Dts9f3k2%3E'
The q parameter is reflected into the results HTML without encoding. A crafted link executes script in the victim's session.
Encode every reflected value for its output context.
HTML-encode q at the template boundary. Never interpolate request parameters into markup without context-aware encoding; add a Content-Security-Policy as defense in depth.
  • https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
Tags: OWASP ASVS V5
LOW
Address in next sprint

Missing Cross-Origin-Resource-Policy header on static assets

#:4
Category:headers
CWE:CWE-942
Status:OPEN
Diff:PERSISTING
URL: https://acme-store.com/assets/logo.png
GET /assets/logo.png → 200 without CORP
Static images are served without Cross-Origin-Resource-Policy, leaving them loadable cross-origin (Cross-Site Imaging).
Serve Cross-Origin-Resource-Policy: same-origin on static assets.
Next.js: set security headers centrally in next.config via the headers() function (or in middleware for dynamic cases) so every route — including API routes and RSC payloads — is covered.
// next.config.ts
const securityHeaders = [
  { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" },
  { key: "Content-Security-Policy", value: "default-src 'self'; object-src 'none'; frame-ancestors 'none'" },
  { key: "X-Content-Type-Options", value: "nosniff" },
  { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
];

export default {
  async headers() {
    return [{ source: "/:path*", headers: securityHeaders }];
  },
};
LOW
Address in next sprint

X-Powered-By header discloses framework

#:5
Category:headers
CWE:CWE-200
Status:OPEN
Diff:PERSISTING
URL: https://acme-store.com/
X-Powered-By: Next.js
The X-Powered-By response header reveals the application framework, narrowing an attacker's reconnaissance.
Remove the X-Powered-By header from all responses.
Next.js: set security headers centrally in next.config via the headers() function (or in middleware for dynamic cases) so every route — including API routes and RSC payloads — is covered.
// next.config.ts
const securityHeaders = [
  { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" },
  { key: "Content-Security-Policy", value: "default-src 'self'; object-src 'none'; frame-ancestors 'none'" },
  { key: "X-Content-Type-Options", value: "nosniff" },
  { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
];

export default {
  async headers() {
    return [{ source: "/:path*", headers: securityHeaders }];
  },
};
INFO
Informational

Technology detected: Next.js 15.1.2

#:6
Category:tech-cve
Status:OPEN
Diff:PERSISTING
URL: https://acme-store.com/
self.__next_f RSC payloads, /_next/static/ asset URLs
The runtime fingerprints as Next.js 15.1.2 (App Router markers). No known CVEs in the curated database apply to this version.
Keep the framework updated as patches ship.