Web App Self-Pentest Checklist
Authorized, rate-limited probe of a web app running on the user's own machine. Follow the shared probing conventions for authorization, target discovery, and output schema.
Procedure
- Authorization preflight. Default to
localhost/127.0.0.1. If a non-loopback host is named, require explicit user confirmation in chat. - Discover base URL per
PROBING.md(env → entrypoint → ask). Recordtarget.base_urlandtarget.discovered_via. - Confirm liveness.
GET /andGET /healthz//health(if any). If unreachable, returnPREFLIGHT-BLOCKED. - Enumerate routes from the app's source if you can read it; otherwise crawl from
/to depth 2 (max 50 URLs) and stop. - Run the rule pack below. Stop at the first request budget hit (default 200 requests).
Rules
| ID | Severity (if confirmed) | Probe | Confirmed when |
|---|---|---|---|
| WEB-INFO-001 | low | Fetch /.env, /.env.local, /.git/config, /.git/HEAD, /package.json, /composer.json |
Body is a non-404 file containing expected markers (DB_, API_KEY, [core]) |
| WEB-INFO-002 | medium | Fetch /server-status, /.well-known/security.txt, /robots.txt, /sitemap.xml, /api-docs, /swagger, /openapi.json, /graphql |
Returns a populated body that exposes routes/internals |
| WEB-AUTH-001 | high | For each mutating route discovered, send the request with no auth header / cookie | 2xx response identical to authenticated response |
| WEB-AUTH-002 | high | Replay an authenticated request from user A's session against /users/{B}/... |
2xx instead of 403 = IDOR |
| WEB-AUTH-003 | medium | Send Authorization: Bearer eyJhbGciOiJub25lIn0.<base64-mod-payload>. (alg=none JWT) |
2xx accepted = JWT alg confusion |
| WEB-XSS-001 | high | Submit "><svg/onload=__probe('xss')> to each text input; render-back endpoints reflect it un-encoded |
<svg/onload appears verbatim in HTML response (not entity-encoded) |
| WEB-SQLI-001 | high | Append ' and ' OR '1'='1 to each numeric/string param; compare against baseline |
Different status code OR DB error string in response |
| WEB-SSRF-001 | high | If app fetches URLs (preview, image proxy, webhook), submit http://127.0.0.1:1, http://169.254.169.254/latest/meta-data/ |
Connection succeeds / metadata returns |
| WEB-OR-001 | medium | Submit redirect param values like //evil.test, https://evil.test to login/return URLs |
30x with Location: outside same-origin |
| WEB-CORS-001 | high | Send Origin: https://evil.test with credentials to authenticated endpoint |
Access-Control-Allow-Origin reflects origin AND Allow-Credentials: true |
| WEB-CSRF-001 | high | State-changing endpoint reachable via cross-origin form POST without CSRF token | 2xx on a request lacking the CSRF header/token |
| WEB-UPLOAD-001 | high | Upload file with double-extension shell.php.jpg / wrong MIME / SVG with embedded script |
Stored and served with executable type / Content-Type: image/svg+xml rendered |
| WEB-MASS-001 | medium | Submit extra fields to update endpoints (role: "admin", is_staff: true) |
Field accepted and persisted = mass-assignment |
| WEB-ERR-001 | low | Trigger errors via /?id[]=1, malformed JSON, type confusion |
Stack trace in 500 response = info disclosure |
| WEB-RATE-001 | medium | Send 10 rapid POST /login with random passwords |
All accepted without 429 / lockout = no rate limiting |
Workflow notes
- Reserve mutation probes (
WEB-MASS-001,WEB-UPLOAD-001,WEB-CSRF-001) for endpoints clearly safe to write to (or skip if uncertain). - For
WEB-AUTH-002(IDOR), require the user to provide two test accounts; otherwise mark asinfo: not-tested. - Render IDs from the running app's data, never inject random UUIDs that match nothing.
Wrong-target safety
If the resolved base_url host is not in {localhost, 127.0.0.1, ::1, *.localhost} AND was not explicitly confirmed by the user this session — return a single PREFLIGHT-BLOCKED finding and stop.
References
- OWASP Web Security Testing Guide: https://owasp.org/www-project-web-security-testing-guide/
- OWASP API Security Top 10: https://owasp.org/API-Security/
- PortSwigger Web Security Academy: https://portswigger.net/web-security