| name | pentest |
| description | Run an authorized penetration test against the project after some implementation exists:
combine static code analysis and dynamic testing against the running app to detect
vulnerabilities, then register each confirmed finding as a GitHub issue. Use once enough
of the project is implemented to be worth probing for security flaws. Invoke with
`/pentest`. The created issues are consumed by `/auto-issue-worker`.
|
| allowed-tools | ["Read","Bash","Grep","Glob","AskUserQuestion"] |
Pentest
You perform an authorized penetration test of the easy-pokedex-v2 repository
(Kurogoma4D/easy-pokedex-v2) and turn the vulnerabilities you confirm into GitHub
issues. This runs after some implementation exists, combining static analysis (reading
the code) and dynamic testing (exercising the running app), then files one issue per
finding so /auto-issue-worker can drive the fixes.
This is a defensive, authorized engagement: you are testing the user's own project to find
and fix its weaknesses. Stay within that scope — see the Rules section.
Project tech stack (use it to focus on the relevant vulnerability classes):
- Language: TypeScript (strict mode), frontend and BFF.
- Frontend: Angular 21 (LTS) — standalone, signal-first, zoneless. SPA served to the browser.
- BFF: Hono on Node.js — the only component that reaches PokeAPI; proxies, aggregates, and caches upstream responses. This is the primary server-side attack surface (input validation, SSRF, cache poisoning, header/CORS handling, rate limiting).
- Data source: PokeAPI (external, read-only upstream).
- Structure: pnpm workspace monorepo —
apps/web (Angular), apps/bff (Hono).
Workflow
Step 1 — Scope and preflight
- Confirm you can reach the repo:
gh repo view Kurogoma4D/easy-pokedex-v2.
- Read
spec.md and README.md to understand the attack surface (entry points, auth model,
external integrations, data stores, trust boundaries).
- Determine how much is implemented and what is testable. If very little exists yet, tell the
user pentesting is premature and stop.
- Work out how to run the app locally for dynamic testing (from
spec.md / README /
run scripts). If it cannot be run locally, note that dynamic testing will be limited to
what is reachable and continue with static analysis.
- Confirm the scope with the user: only this repository and its locally-run instance are in
scope. Do not test any deployed/shared/production environment unless the user
explicitly authorizes a specific target.
Step 2 — Static analysis (SAST)
Read the code and look for vulnerability classes, prioritised by the tech stack above. Cover
at least the OWASP Top 10 categories that apply:
- Injection (SQL/NoSQL/command/template) and unsafe query construction.
- Broken authentication / session management and broken access control (missing authz checks,
IDOR, privilege escalation paths).
- Sensitive data exposure: hardcoded secrets, credentials in source/config, weak crypto,
secrets in logs.
- SSRF, path traversal, unrestricted file upload, insecure deserialization.
- XSS / CSRF / missing security headers for web surfaces.
- Vulnerable or outdated dependencies (check lockfiles; run an audit tool if available, e.g.
npm audit, pip-audit, cargo audit, govulncheck).
- Misconfiguration: permissive CORS, debug endpoints, default credentials, exposed admin.
Record each candidate with file/line references and the reason it looks exploitable.
Step 3 — Dynamic testing (DAST)
For each static candidate and for the app's exposed surface:
- Start the app locally (per Step 1), targeting
localhost only.
- Send crafted requests/inputs to confirm whether the candidate is actually exploitable
(e.g. an injection payload that alters behaviour, an unauthenticated request that returns
protected data, a traversal that reads an out-of-scope file).
- Observe and capture the evidence (request, response, observed effect) needed to reproduce.
- Use non-destructive payloads. Do not exfiltrate real data, drop tables, or run
denial-of-service style load. Prove the vulnerability with the minimum necessary action.
- Tear the app down when finished.
A finding moves from "candidate" to "confirmed" only when you have reproduced it.
Step 4 — Triage and confirm with the user
Consolidate findings before creating any issues:
- Drop false positives; keep confirmed vulnerabilities and clearly-justified high-likelihood ones.
- Assign each a severity (Critical / High / Medium / Low) based on impact and exploitability.
- De-duplicate findings that share one root cause into a single issue.
- Present the findings as a table and get the user's approval on what to file:
| # | Title | Severity | Type (OWASP) | Location | Confirmed? |
|---|
- Do not create issues until the user approves the list.
Step 5 — Create the issues
For each approved finding, create an issue with gh. Keep the body compatible with
/auto-issue-worker:
gh issue create \
--repo Kurogoma4D/easy-pokedex-v2 \
--title "[security] <concise vulnerability title>" \
--label "security" \
--body "$(cat <<'EOF'
## Summary
<The vulnerability and its impact, in one or two sentences.>
## Severity
<Critical | High | Medium | Low> — <OWASP category>
## Location
<file:line references and/or affected endpoint>
## Reproduction
<Minimal steps / request that demonstrates the vulnerability. Redact any real secrets.>
## Remediation
<Recommended fix.>
## Acceptance Criteria
- [ ] The vulnerability is no longer reproducible by the steps above
- [ ] The fix does not regress existing functionality
- [ ] E2E behavior is verified and guaranteed at the completion of this task
## Dependencies
- <Depends on #<n>, or "None">
EOF
)"
Rules for issue creation:
- Apply a
security label (create it with gh label create security if missing, after
confirming with the user). Add a severity label too if the project uses them.
- Order issues by severity (Critical/High first) so they surface earlier to
/auto-issue-worker.
- Redact real secrets from issue bodies — describe the location, never paste the value.
- Every issue's Acceptance Criteria must include
"E2E behavior is verified and guaranteed at the completion of this task".
Step 6 — Report
- Print a summary table mapping each finding to its severity and created issue number/URL.
- Note any findings you could not fully confirm and why.
- Tell the user they can run
/auto-issue-worker to drive the fixes.
Rules
- Authorized scope only: test only this repository and its locally-run instance. Never
attack third-party systems, shared staging, or production without explicit, specific
authorization from the user.
- Non-destructive: no DoS, no destructive payloads, no exfiltration of real data. Prove
each issue with the minimum necessary action.
- Never create issues before the user approves the findings list (Step 4).
- Each issue must be self-contained: reproduction steps plus remediation in the body.
- Redact secrets and sensitive data from all issue bodies and reports.
- Use the same language as
spec.md for issue titles and bodies.
- If
gh fails (auth, permissions, missing repo), report the error clearly and stop.