cspt-csrf
Surface CSPT-to-CSRF candidates — path traversal landing in fetch/XHR/axios URLs. Scans dom_reachable.jsonl for cspt_* sinks, ranks by verb severity, writes cspt_csrf.jsonl. Run after dom-xss-hunt, be
SKILL.md.claude/skills/cspt-csrf/SKILL.md
GitHubcspt-csrf
Purpose
Doyensec's CSPT2CSRF research showed that chains where attacker
controls a path segment of a fetch/XHR URL can be escalated to CSRF on
cookie-authenticated mutation endpoints. This skill is the static-pass
candidate generator. Live confirmation is browser-confirm.
Inputs
targets/<name>/chains/dom_reachable.jsonl(preferred) orchains/hot.jsonl.targets/<name>/db/js_analyzer.db(per-target snapshot — used to cross-checkcspt_path_traversal_markertags from theextra_cspt.jsontaxonomy).
Steps
- Ensure
dom-xss-hunthas producedchains/dom_reachable.jsonl, or fall back tochains/hot.jsonl. - Run:
python3 bin/cspt_csrf_scan.py targets/<name> - Inspect
chains/cspt_csrf.jsonl. Each line:{ "chain_id": "...", "kind": "cspt_csrf_candidate", "severity": "critical|high|medium|low", "sink": { "qname", "file", "line", "taxonomy_id" }, "source": { ... }, "path": [...], "mutating_verb_hint": bool, "has_path_traversal_marker": bool } - For each candidate (start with
critical), feed intobrowser-confirmlive mode with a CSPT-style PoC: a same-origin request whose URL contains a path-traversal segment that pivots to a different endpoint. Verify the cookie is sent automatically (no Authorization header that would otherwise gate CSRF). - Confirmed CSPT-CSRF chains write to
targets/<name>/findings/<chain_id>/confirmed.jsonwithkind: cspt_csrfplus the redirected endpoint.
Outputs
targets/<name>/chains/cspt_csrf.jsonlstatus.json.phases.cspt_csrf
Failure modes
chains_scanned == 0→ runchain-triageanddom-xss-huntfirst.matched_cspt_sink == 0→ indexer didn't tag any chain sink with a CSPT-family taxonomy. Verifyextra_cspt.jsonis loaded (taxonomy.load_default()auto-loadsextra_*.json); re-runjs-index.with_path_traversal_marker == 0→ CSPT family hits exist but no path-traversal markers were tagged on intermediate nodes. Lower- confidence candidates still emit; mark accordingly duringbrowser-confirm.
Result block
"phases": { "cspt_csrf": {
"status": "done", "ts": "<iso>",
"input": "chains/...jsonl",
"chains_scanned": N,
"matched_cspt_sink": N,
"with_path_traversal_marker": N,
"candidates_written": N,
"output_file": "chains/cspt_csrf.jsonl" } }