0x0pointer / 0x0pointer/agent-smith

ZAP sub-tool never runs: `spider` deep/thorough modes silently degrade to katana + playwright

Open
#183 0 comments 0 reactions 0 assignees View on GitHub

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
  1. 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.
  2. Proper fix: drop zap-cli entirely — see the companion issue.
  3. 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:46 lists mode=fast|playwright and omits deep / thorough entirely.
  • The /pentester skill describes mode=deep (ZAP + AJAX) — a path that does nothing.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.