0x0pointer / 0x0pointer/agent-smith
ZAP sub-tool never runs: `spider` deep/thorough modes silently degrade to katana + playwright
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 129
- Forks
- 10
- Avg merge
- 8h 52m
- Merged PRs (30d)
- 5
Description
What happens
scan(tool="spider", mode="deep") and mode="thorough" both advertise ZAP as a sub-tool. In practice ZAP contributes nothing, because zap-cli is not present in the Kali image. Every run emits only the guard message.
From this engagement's logs:
$ grep -h 'zap-ajax skipped' logs/ artifacts/ -r | sort | uniq -c
3 [zap-ajax skipped: zap-cli not installed in the Kali image]
2026-09-17T11:01:27Z NOTE spider: thorough mode — katana + playwright + zap-ajax (per-subtool timeout=2400s)
2026-09-17T11:01:53Z TOOL_RESULT spider
2026-09-17T11:01:54Z NOTE spider auto-discovery: {'registered': 2, 'cells': 21, 'by_source': {'spider': 2}, ...}
The whole "thorough" spider registered 2 endpoints. I ended up hand-writing a recursive authenticated crawler to get usable coverage (66 URLs), which is the workaround this bug forces.
Root cause — two graceful degradations chained into a silent permanent failure
Build time, tools/kali/Dockerfile:157-158:
RUN [ "$INSTALL_WEB" = "1" ] || { echo "[web] skipped"; exit 0; }; \
pip3 install --no-cache-dir zapcli --break-system-packages || echo "WARN: pip install zapcli failed (continuing)"
The comment above it is candid: "zapcli is old, so a build-time pip failure must not abort the image — spider.py already guards command -v zap-cli and skips cleanly if absent."
Run time, mcp_server/scan_tools/spider.py:39-43 (thorough) and :79-82 (deep):
zap_cmd = (
f"if command -v zap-cli >/dev/null 2>&1; then "
f"zap-cli --port 8090 --api-key zapscan quick-scan --spider --ajax-spider "
f"--start-options '-config api.key=zapscan -port 8090' {safe_url}; "
f"else echo '[zap-ajax skipped: zap-cli not installed in the Kali image]'; fi"
)
Each guard is individually reasonable. Together they mean the install can fail on every build and the runtime treats permanent absence as a routine skip — so a sub-tool that has never worked looks like a deliberate opt-out. Note zaproxy (the daemon) is installed via apt at Dockerfile:151; only the CLI wrapper that drives it is missing.
Why zapcli fails to install
zap-cli is discontinued: latest release 0.12.2, ~5 years old, maintenance status Inactive, no recent PR or issue activity. It is not expected to install cleanly on a current Python.
Why this matters
mode="deep"is documented as a ZAP mode and is a no-op end to end.mode="thorough"claims three sub-tools and delivers two.- The failure is invisible in the envelope: the spider returns success with partial output.
- Coverage silently suffers, and the agent cannot tell the difference between "ZAP found nothing" and "ZAP never ran".
Expected
Either ZAP runs, or the tool reports a hard error. A sub-tool that cannot run should not be advertised as having run.
Suggested fix
- Short term: fail loudly — surface the missing sub-tool as a warning in the envelope, and make
mode="deep"return an explicit error rather than a no-op, so nobody reads its empty output as a clean result. - Proper fix: drop
zap-clientirely — see the companion issue. - Add a build-time smoke test asserting each advertised sub-tool binary exists in the image. Related: the same "empty output reported as success" pattern affects semgrep/trufflehog.
Docs to update alongside
CLAUDE.md:46listsmode=fast|playwrightand omitsdeep/thoroughentirely.- The
/pentesterskill describesmode=deep (ZAP + AJAX)— a path that does nothing.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with tools/kali/Dockerfile:151-158 and mcp_server/scan_tools/spider.py:39-43 and :79-82; compare the advertised modes with installed commands and guard behavior. Check CLAUDE.md:46 and the /pentester skill for the documented modes. Done means missing ZAP is surfaced distinctly, deep cannot appear to complete cleanly, and advertised sub-tools have image smoke coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, python
- Domain
- devops, documentation, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100