Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion capabilities/web-security/capability.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schema: 1
name: web-security
version: "2.0.3"
version: "2.0.4"
description: >
Web application penetration testing with 83 attack technique playbooks
covering HTTP desync/request smuggling, cache poisoning, SSRF, SSTI, DOM
Expand Down
8 changes: 7 additions & 1 deletion capabilities/web-security/docker/Dockerfile.runtime
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,15 @@ RUN pip install --no-cache-dir \
"fastmcp>=2.0" \
"httpx>=0.28" \
"caido-sdk-client>=0.3.0" \
"pacu" \
"ast-grep-cli"

# ── Pacu (AWS exploitation framework) ───────────────────────────────
# Own tool environment: pacu pins urllib3<2 and botocore<1.32, which would
# downgrade the packages above. The venv lives outside /root so `runner` can
# run it; the launcher is linked into /usr/local/bin.
RUN UV_TOOL_DIR=/opt/uv-tools UV_TOOL_BIN_DIR=/usr/local/bin \
uv tool install --python /usr/bin/python3 pacu==1.7.0

# ── fireprox (AWS API Gateway IP rotation) ──────────────────────────
# Installed to a predictable path; requires AWS credentials at runtime.
RUN git clone --depth 1 https://github.com/ustayready/fireprox /root/git/fireprox \
Expand Down
4 changes: 3 additions & 1 deletion capabilities/web-security/scripts/install_tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,10 @@ install_waymore() {
run_stage waymore install_waymore

# -- Pacu (AWS exploitation framework) ----------------------------------------
# Installed in its own uv tool environment: pacu pins urllib3<2 and
# botocore<1.32, which would downgrade the shared sandbox venv.
install_pacu() {
have pacu || retry py_install pacu || { echo "WARN: pacu install failed, skipping" >&2; return 1; }
have pacu || retry uv tool install pacu==1.7.0 || { echo "WARN: pacu install failed, skipping" >&2; return 1; }
}
run_stage pacu install_pacu

Expand Down
17 changes: 17 additions & 0 deletions capabilities/web-security/tests/test_install_tools_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -811,3 +811,20 @@ def test_sealed_install_checks_local_tools_without_fetches_or_retries(
assert "WARN: optional artifact unavailable:" in result.stderr
if missing_required:
assert "Missing required tool: nuclei" in result.stderr


class TestPacuOwnToolEnvironment:
"""pacu pins urllib3<2 and botocore<1.32, so it must not share the venv."""

def test_install_script_uses_isolated_uv_tool(self) -> None:
stage = _shell_function("install_pacu")
assert "have pacu || retry uv tool install pacu==1.7.0" in stage
assert "py_install pacu" not in INSTALL_SCRIPT

def test_runtime_image_installs_pacu_in_own_environment(self) -> None:
dockerfile = (ROOT / "docker" / "Dockerfile.runtime").read_text(
encoding="utf-8"
)
assert "uv tool install" in dockerfile
assert "pacu==1.7.0" in dockerfile
assert not re.search(r'^\s*"pacu"', dockerfile, re.M)
Loading