Compare commits

...
Author SHA1 Message Date
BaaRai ac003ede28 chore(docker): verify tool downloads and pin build inputs
Stage the recon binaries in a build-platform "tools" stage and verify each
release archive against the checksums file of its own GitHub release (exact
asset name, sha256), failing the build when the entry is missing or does not
match: nuclei v3.11.1, httpx v1.12.0, subfinder v2.17.0, katana v1.8.0,
ffuf v2.3.0, dalfox v3.2.4. sqlmap is cloned at tag 1.9.9 and checked
against commit cceda39208b5aad478de2c3f731df4239d9881f6 before .git is
removed. The runtime stage copies /out/ and /opt/sqlmap from that stage.

Install Node v22.23.4 from the official nodejs.org tarball verified against
SHASUMS256.txt instead of piping the NodeSource setup script into bash.

Pin @playwright/mcp@0.0.83, @playwright/cli@0.1.22 and playwright@1.64.1
instead of @latest.

amd64 and arm64 are mapped explicitly; any other architecture fails the
build. dalfox --version no longer ignores failures.

Carries over the Dockerfile part of #127 by stevenAthompson.
2026-11-11 20:38:33 +01:00
BaaRai 31e56a16fc Merge pull request #187 from BaaRai/fix/customtool-proxy-scheme
Fix doubled scheme in the custom http tool's recording proxy URL
2026-11-11 20:27:16 +01:00
+90 -37
View File
@@ -43,51 +43,101 @@ RUN ARTEX_SKIP_FRONTEND=1 \
ARTEX_BUILD_VERSION="${ARTEX_VERSION}" \
bash ./build.sh --target "${TARGETOS:-linux}/${TARGETARCH:-amd64}"
# ---------------------------------------------------------------- runtime ---
FROM python:3.12-slim-bookworm
# ------------------------------------------------------- third-party tools ---
# Web-recon toolbox (drost-community take 1, #100): pinned release binaries, staged
# on the build platform and copied into /usr/local/bin of the runtime image so hunt
# workers can run them directly through their Bash tool. Versions pinned per tool;
# upgrade deliberately. Each archive is verified against the checksums file of its
# own GitHub release (exact asset name, sha256). That file comes from the same
# release channel as the archive, so it catches corrupted or swapped downloads and
# moved tags, not a compromised publisher. sqlmap has no release binaries: it is a
# shallow clone of a pinned tag, checked against the expected commit.
FROM --platform=$BUILDPLATFORM debian:bookworm-slim AS tools
ARG TARGETARCH
# Common tools: ripgrep / curl / vim, plus a set of recon staples (add/remove as needed).
# Node 22.x comes from NodeSource: bookworm's apt nodejs is 18, Playwright requires >=20,
# and 20 is end-of-life. 22 matches the CI and release workflows.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates ripgrep curl wget vim git jq unzip \
dnsutils iputils-ping netcat-openbsd inetutils-telnet whois nmap \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# Web-recon toolbox (drost-community take 1, #100): pinned release binaries installed
# into /usr/local/bin so hunt workers can run them directly through their Bash tool.
# Versions pinned per tool; upgrade deliberately. sqlmap is a python checkout (no
# release binaries) symlinked into PATH.
ARG NUCLEI_VERSION=v3.11.1
ARG HTTPX_VERSION=v1.12.0
ARG SUBFINDER_VERSION=v2.17.0
ARG KATANA_VERSION=v1.8.0
ARG FFUF_VERSION=v2.3.0
ARG DALFOX_VERSION=v3.2.4
ARG SQLMAP_VERSION=1.9.9
ARG SQLMAP_COMMIT=cceda39208b5aad478de2c3f731df4239d9881f6
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl git unzip \
&& rm -rf /var/lib/apt/lists/*
RUN set -eux; \
case "${TARGETARCH:-amd64}" in \
amd64) PD_ARCH=amd64; FFUF_ARCH=amd64; DALFOX_ARCH=x86_64 ;; \
arm64) PD_ARCH=arm64; FFUF_ARCH=arm64; DALFOX_ARCH=aarch64 ;; \
*) echo "unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; \
esac; \
mkdir -p /out; \
fetch() { base="$1"; asset="$2"; sums="$3"; name="$4"; \
rm -rf /tmp/t; mkdir -p /tmp/t/x; \
curl -fsSL "$base/$asset" -o "/tmp/t/$asset"; \
curl -fsSL "$base/$sums" -o /tmp/t/sums.txt; \
want="$(awk -v a="$asset" '$2 == a || $2 == "*" a { print $1 }' /tmp/t/sums.txt)"; \
if [ -z "$want" ]; then echo "no checksum entry for $asset" >&2; exit 1; fi; \
got="$(sha256sum "/tmp/t/$asset" | cut -d' ' -f1)"; \
if [ "$want" != "$got" ]; then echo "checksum mismatch for $asset: want $want got $got" >&2; exit 1; fi; \
case "$asset" in *.zip) unzip -q "/tmp/t/$asset" -d /tmp/t/x ;; *) tar -xzf "/tmp/t/$asset" -C /tmp/t/x ;; esac; \
find /tmp/t/x -type f -name "$name" -exec install -m 0755 {} /out/ \; ; \
[ -x "/out/$name" ] || { echo "$name not found in $asset" >&2; exit 1; }; \
rm -rf /tmp/t; }; \
gh="https://github.com"; \
fetch "$gh/projectdiscovery/nuclei/releases/download/$NUCLEI_VERSION" \
"nuclei_${NUCLEI_VERSION#v}_linux_${PD_ARCH}.zip" "nuclei_${NUCLEI_VERSION#v}_checksums.txt" nuclei; \
fetch "$gh/projectdiscovery/httpx/releases/download/$HTTPX_VERSION" \
"httpx_${HTTPX_VERSION#v}_linux_${PD_ARCH}.zip" "httpx_${HTTPX_VERSION#v}_checksums.txt" httpx; \
fetch "$gh/projectdiscovery/subfinder/releases/download/$SUBFINDER_VERSION" \
"subfinder_${SUBFINDER_VERSION#v}_linux_${PD_ARCH}.zip" "subfinder_${SUBFINDER_VERSION#v}_checksums.txt" subfinder; \
fetch "$gh/projectdiscovery/katana/releases/download/$KATANA_VERSION" \
"katana_${KATANA_VERSION#v}_linux_${PD_ARCH}.zip" "katana-${KATANA_VERSION#v}-checksums.txt" katana; \
fetch "$gh/ffuf/ffuf/releases/download/$FFUF_VERSION" \
"ffuf_${FFUF_VERSION#v}_linux_${FFUF_ARCH}.tar.gz" "ffuf_${FFUF_VERSION#v}_checksums.txt" ffuf; \
fetch "$gh/hahwul/dalfox/releases/download/$DALFOX_VERSION" \
"dalfox-${DALFOX_VERSION}-linux-${DALFOX_ARCH}-musl.tar.gz" "dalfox-${DALFOX_VERSION}-linux-${DALFOX_ARCH}-musl.tar.gz.sha256" dalfox; \
git clone --quiet --depth 1 --branch "$SQLMAP_VERSION" https://github.com/sqlmapproject/sqlmap /opt/sqlmap; \
commit="$(git -C /opt/sqlmap rev-parse HEAD)"; \
if [ "$commit" != "$SQLMAP_COMMIT" ]; then echo "sqlmap commit mismatch: want $SQLMAP_COMMIT got $commit" >&2; exit 1; fi; \
rm -rf /opt/sqlmap/.git
# ---------------------------------------------------------------- runtime ---
FROM python:3.12-slim-bookworm
ARG TARGETARCH
# Common tools: ripgrep / curl / vim, plus a set of recon staples (add/remove as needed).
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates ripgrep curl wget vim git jq unzip xz-utils \
dnsutils iputils-ping netcat-openbsd inetutils-telnet whois nmap \
&& rm -rf /var/lib/apt/lists/*
# Node 22 from the official nodejs.org tarball, verified against its SHASUMS256.txt:
# bookworm's apt nodejs is 18, Playwright requires >=20, and 20 is end-of-life.
# 22 matches the CI and release workflows.
ARG NODE_VERSION=22.23.4
RUN set -eux; \
case "${TARGETARCH:-amd64}" in \
amd64) NODE_ARCH=x64 ;; \
arm64) NODE_ARCH=arm64 ;; \
*) echo "unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; \
esac; \
base="https://nodejs.org/dist/v${NODE_VERSION}"; \
asset="node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz"; \
curl -fsSL "$base/$asset" -o "/tmp/$asset"; \
curl -fsSL "$base/SHASUMS256.txt" -o /tmp/SHASUMS256.txt; \
want="$(awk -v a="$asset" '$2 == a { print $1 }' /tmp/SHASUMS256.txt)"; \
if [ -z "$want" ]; then echo "no checksum entry for $asset" >&2; exit 1; fi; \
got="$(sha256sum "/tmp/$asset" | cut -d' ' -f1)"; \
if [ "$want" != "$got" ]; then echo "checksum mismatch for $asset: want $want got $got" >&2; exit 1; fi; \
tar -xJf "/tmp/$asset" -C /usr/local --strip-components=1 --no-same-owner; \
rm -f "/tmp/$asset" /tmp/SHASUMS256.txt; \
node --version; npm --version
# Pinned, checksum-verified recon binaries and the sqlmap checkout from the tools stage.
COPY --from=tools /out/ /usr/local/bin/
COPY --from=tools /opt/sqlmap /opt/sqlmap
RUN set -eux; \
base="https://github.com"; \
pd_fetch() { repo="$1"; ver="$2"; name="$3"; nov="${ver#v}"; \
curl -fsSL "$base/$repo/releases/download/$ver/${name}_${nov}_linux_${TARGETARCH}.zip" -o /tmp/t.zip \
&& unzip -o -q /tmp/t.zip -d /tmp/td \
&& find /tmp/td -type f -name "$name" -exec install -m 0755 {} /usr/local/bin/ \; \
&& rm -rf /tmp/t.zip /tmp/td; }; \
case "$TARGETARCH" in amd64) FFUF_ARCH=amd64; DALFOX_ARCH=x86_64;; arm64) FFUF_ARCH=arm64; DALFOX_ARCH=aarch64;; esac; \
pd_fetch projectdiscovery/nuclei "$NUCLEI_VERSION" nuclei; \
pd_fetch projectdiscovery/httpx "$HTTPX_VERSION" httpx; \
pd_fetch projectdiscovery/subfinder "$SUBFINDER_VERSION" subfinder; \
pd_fetch projectdiscovery/katana "$KATANA_VERSION" katana; \
tar_fetch() { url="$1"; name="$2"; \
curl -fsSL "$url" -o /tmp/t.tgz \
&& mkdir -p /tmp/td && tar -xzf /tmp/t.tgz -C /tmp/td \
&& find /tmp/td -type f -name "$name" -exec install -m 0755 {} /usr/local/bin/ \; \
&& rm -rf /tmp/t.tgz /tmp/td; }; \
tar_fetch "$base/ffuf/ffuf/releases/download/$FFUF_VERSION/ffuf_${FFUF_VERSION#v}_linux_${FFUF_ARCH}.tar.gz" ffuf; \
tar_fetch "$base/hahwul/dalfox/releases/download/$DALFOX_VERSION/dalfox-${DALFOX_VERSION}-linux-${DALFOX_ARCH}-musl.tar.gz" dalfox; \
git clone --depth 1 https://github.com/sqlmapproject/sqlmap /opt/sqlmap; \
ln -s /opt/sqlmap/sqlmap.py /usr/local/bin/sqlmap; \
nuclei -version >/dev/null; httpx -version; subfinder -version; katana -version; \
ffuf -V >/dev/null; dalfox --version >/dev/null 2>&1 || true; sqlmap --version >/dev/null
ffuf -V >/dev/null; dalfox --version >/dev/null; sqlmap --version >/dev/null
# bbot recursive recon orchestrator (#117): blacklanternsecurity/bbot, AGPL-3.0
# (same license as ARTEX; standalone CLI dependency, not linked code). Pinned
@@ -111,8 +161,11 @@ RUN set -eux; \
# @playwright/cli: provides playwright-cli, verified with --help right after install.
# Then install playwright (browser management) and preinstall chromium plus its system
# dependencies via --with-deps, so MCP/CLI work on first start inside the container
# without downloading browsers over the network.
RUN npm install -g @playwright/mcp@latest @playwright/cli@latest playwright@latest \
# without downloading browsers over the network. All three are pinned; upgrade deliberately.
ARG PLAYWRIGHT_MCP_VERSION=0.0.83
ARG PLAYWRIGHT_CLI_VERSION=0.1.22
ARG PLAYWRIGHT_VERSION=1.64.1
RUN npm install -g "@playwright/mcp@${PLAYWRIGHT_MCP_VERSION}" "@playwright/cli@${PLAYWRIGHT_CLI_VERSION}" "playwright@${PLAYWRIGHT_VERSION}" \
&& playwright-cli --help \
&& playwright install --with-deps chromium \
&& rm -rf /var/lib/apt/lists/*