--- name: pentest-audit description: "Pentest and security-audit a running Spring Boot app — OWASP ZAP DAST scans, manual probes for auth, headers, CORS, actuator, and error leakage, and a findings report with fixes. Use when asked to pentest an app, run a DAST scan, or audit whether an app is secure end to end. Not for dependency/SBOM/image scanning — use security-hardening. Not for adding auth — use spring-security." --- # Pentest Audit Skill Attacks a running Spring Boot app like an external adversary, then reports what held and what broke. Runtime testing only — build-time scanning (dependencies, SBOM, container images) belongs to `security-hardening`. `SKILL_DIR` = directory containing this SKILL.md file. Only ever run this against apps the user owns or is authorized to test. Confirm the target is theirs before sending a single probe. Load `SKILL_DIR/references/pentest-checklist.md` before Step 4 — it has the exact probe commands and pass/fail criteria. --- ## Step 0 — Gather inputs | Field | Required | Notes | |-------|----------|-------| | `targetUrl` | No | `http://localhost:8080` (default) | | `authToken` | No | valid JWT/session for authenticated probes — ask the user | | `openApiUrl` | No | auto-detected: try `/v3/api-docs` | | `scope` | No | path prefix to limit scanning (e.g. `/api`) | If the app handles real user data or runs beyond localhost, confirm written authorization before continuing. Next: read the project to know what you are attacking. --- ## Step 1 — Read the project ```bash cat pom.xml grep -rn "SecurityFilterChain\|@PreAuthorize\|permitAll" src/main/java/ | head -20 cat src/main/resources/application.yml 2>/dev/null || cat src/main/resources/application.properties grep -rn "management.endpoints\|actuator" src/main/resources/ 2>/dev/null ``` Note for later: which endpoints exist, which are public, whether Spring Security is present, and what actuator exposes. Next: quick static sweep before spending time on runtime probes. --- ## Step 2 — Static sweep Fast greps that often end the audit early: ```bash grep -rn "csrf.disable\|csrf(AbstractHttpConfigurer::disable)" src/main/java/ grep -rn "permitAll" src/main/java/ grep -rn "password\s*=\s*\"\|secret\s*=\s*\"\|apiKey\s*=\s*\"" src/main/ --include=*.java --include=*.yml grep -rn "DEBUG\|TRACE" src/main/resources/application.yml 2>/dev/null grep -rn "allowedOrigins(\"\\*\")\|allowedOriginPatterns(\"\\*\")" src/main/java/ ``` Each hit is a candidate finding — confirm or discard it with a runtime probe in Step 4. Next: start the app. --- ## Step 3 — Run the app ```bash ./mvnw spring-boot:run # or, if docker-compose.yml exists: docker compose up -d ``` Wait for readiness: ```bash until curl -sf -o /dev/null http://localhost:8080/actuator/health || curl -sf -o /dev/null http://localhost:8080/; do sleep 2; done ``` If the app needs external services (database, broker), use the project's compose file — do not stub them; the audit must hit the real stack. Next: manual probes. --- ## Step 4 — Manual probes Work through `SKILL_DIR/references/pentest-checklist.md` top to bottom. For every probe record: the command, the response evidence, and PASS or FAIL with one line of why. Do not skip the authenticated probes when `authToken` was provided — IDOR and method tampering only show up with a valid identity. Next: automated DAST with ZAP. --- ## Step 5 — OWASP ZAP scan ZAP runs in Docker; the image is `ghcr.io/zaproxy/zaproxy:2.17.0`. Before writing, confirm `2.17.0` is still the latest release (see https://github.com/zaproxy/zaproxy/releases/tag/v2.17.0): ```bash curl -s "https://api.github.com/repos/zaproxy/zaproxy/releases/latest" \ | python3 -c "import json,sys; print(json.load(sys.stdin)['tag_name'])" ``` Baseline scan (passive + light active, safe default): ```bash docker run --rm --network host -v "$PWD/zap:/zap/wrk:rw" \ ghcr.io/zaproxy/zaproxy:2.17.0 zap-baseline.py \ -t http://localhost:8080 -r zap/baseline-report.html ``` API scan when an OpenAPI doc exists (much better coverage than spidering): ```bash docker run --rm --network host -v "$PWD/zap:/zap/wrk:rw" \ ghcr.io/zaproxy/zaproxy:2.17.0 zap-api-scan.py \ -t http://localhost:8080/v3/api-docs -f openapi -r zap/api-report.html ``` Notes: - `--network host` so the container reaches localhost; on Docker Desktop use `host.docker.internal` as the target instead. - Add `-z "-connection timeoutInMs=10000"` if the app is slow. - A full active scan (`zap-full-scan.py`) mutates data aggressively — only with explicit user approval, never against shared environments. If there is no OpenAPI doc, offer to add one with `api-design` — the API scan is where ZAP earns its keep. Next: write the report. --- ## Step 6 — Report Copy `SKILL_DIR/assets/templates/pentest-report.md` to `pentest-report.md` in the project root and fill it in: - Verdict first: SECURE ENOUGH TO SHIP / NEEDS FIXES / NOT SAFE TO EXPOSE. - One findings row per confirmed issue: severity, endpoint, evidence, fix. - ZAP alerts triaged — dedupe, drop informational noise, map each to a real fix or a justified dismissal. - Verified-good controls listed so the next audit knows what held. Hand off fixes: - Auth, JWT, roles, method security → apply `spring-security`. - Dependency CVEs, SBOM, image scanning, security CI → apply `security-hardening`. - Missing OpenAPI doc → apply `api-design`. Next step for the user: fix the Critical/High findings, then re-run this audit to confirm.