Tutorial: Web app pentest
A realistic engagement: a customer-facing web app with login, a public marketing surface, an admin path that’s out of scope, and a deliverable you can hand the customer at the end.
Scenario
- Target.
https://app.acme.com(production) - Marketing pages at
https://acme.com— public, in scope for crawl, out of scope for active testing. - Admin panel at
https://app.acme.com/admin— out of scope per the SOW. - Auth. Session-cookie login. We have a non-privileged test
account
[email protected]. - Goal. Verified findings, OWASP + PCI-DSS evidence, customer-ready DOCX inside a 2-hour window.
Inputs you need
| Item | Where it goes |
|---|---|
| Target URL | --target / dashboard Target URL |
| Test credentials | --username / --password (CLI) or Headers / Auth card (dashboard) |
| Authorization text | consent_payload.authorization_text (CLI prompts; dashboard collects on first scan) |
| Exclude paths | --exclude / Exclude paths (one per line) |
Time budget
| Phase | Wall time |
|---|---|
| Recon + crawl | 5-8 min |
| Scan modules (standard) | 20-30 min |
| Active verification + chains | 5-10 min |
| Report generation | < 1 min |
| Total | ~45 min for standard, ~90 min for deep |
Steps
1. Register the target
Open the dashboard at app.pencheff.com,
click Register target, and fill in:
- URL —
https://app.acme.com - Name —
Acme app — production - Exclude paths —
/admin,/internal(one per line) - Attached repositories — pick the connected repo backing this app, if any. The URL scan’s assessment page then deep-links to the repo’s own SAST page.
For a programmatic flow, the same shape goes via
POST /targets with the API key.
2. Scan it
pencheff scan \
--target https://app.acme.com \
--profile standard \
--username [email protected] \
--password "$ACME_PASSWORD" \
--output ./reports/ \
--format docx \
--save-historyFor an SPA, switch to --profile deep — the deep profile
auto-engages a Playwright crawler and persists a STRIDE / DREAD
threat model. Pass --engagement-id $ID
when you want the scan to roll into an existing engagement instead
of the auto-created one.
3. Verify before reporting
The scan’s assessment page shows every flagged finding with its
verification state. By default the report contains only
true_positive rows — click into each unverified row, run
Recheck or use test_endpoint from the MCP host to confirm with
a hand-crafted PoC.
test_endpoint(session_id=sid,
endpoint="/api/orders/12345",
params={"id": "12345' OR 1=1--"})
→ "extracted 17 rows from orders table"4. Look at the chains
exploit_chain_suggest runs in standard and deep. Open the
Chains card on the assessment page and read the top three
proposed chains:
- SSRF → cloud metadata → IAM credential theft → S3 read
- XSS → session theft → admin impersonation
- IDOR → user enumeration → admin
Click Verify on any chain — test_chain runs each step and
records the evidence end-to-end.
5. Open the compliance + threat model
Two cards on the assessment page:
- § Threat model — STRIDE / DREAD model attached to the
auto-created engagement (
deepprofile only). - § Compliance mapping — per-scan rollup across OWASP Top 10, PCI-DSS, NIST 800-53, SOC 2, ISO 27001:2022, HIPAA. Open it to filter by framework and copy the controls into your SOW.
6. Ship the deliverable
# Already in ./reports/ from the scan command above.
ls reports/
# pencheff-acme-app-2026-05-08.docx
# pencheff-acme-app-2026-05-08.json
# pencheff-acme-app-2026-05-08.csv
# DOCX is what you hand the customer.
open reports/pencheff-acme-app-2026-05-08.docxThe DOCX carries:
- Executive summary
- Scope + authorization text + consent timestamp
- Threat model (deep-profile only)
- Findings register (verified only by default)
- Compliance appendix (every framework that fired)
- Methodology + tooling list
Customer-ready brand. Per-workspace branding (logo, colors,
opening letter, methodology, footer) is stamped on the DOCX cover.
Configure it once at /settings/branding.
Deliverable
A single .docx you can email a customer plus the matching .json
that a procurement system can ingest. Both carry the same compliance
mapping; the JSON is the source of truth.
Next
- Tutorial: SPA + authenticated crawl — same flow, harder login.
- Tutorial: API + OpenAPI seed
- CI gate — same scan, blocking PRs.