diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a38b0b0..e665d72 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -249,6 +249,62 @@ jobs: jq -e --arg version "${RELEASE_TAG#v}" '.ok == true and .version == $version' /tmp/artex-health.json curl --fail http://127.0.0.1:8787/ > /tmp/artex-index.html grep -qi ' minimum[i]) process.exit(0); + if (actual[i] < minimum[i]) process.exit(1); + } + ' + if curl --fail --silent --show-error --max-time 15 \ + https://dv-g3b-emudhra.we-have-a-problem.com/ >/dev/null; then + echo "curl accepted a certificate from a compromised eMudhra CA" >&2 + exit 1 + fi + if node -e ' + fetch("https://dv-g3b-emudhra.we-have-a-problem.com/") + .then(() => process.exit(0), () => process.exit(1)) + '; then + echo "Node accepted a certificate from a compromised eMudhra CA" >&2 + exit 1 + fi + NODE_PATH="$(npm root -g)" node <<'NODE' + const { chromium } = require("playwright"); + + (async () => { + const browser = await chromium.launch({ headless: true, args: ["--no-sandbox"] }); + const page = await browser.newPage(); + try { + await page.goto("https://dv-g3b-emudhra.we-have-a-problem.com/", { + waitUntil: "domcontentloaded", + timeout: 15000, + }); + console.error("Chromium accepted a certificate from a compromised eMudhra CA"); + process.exitCode = 1; + } catch (error) { + const message = String(error); + if (!/ERR_CERT_|CERT_/.test(message)) { + console.error(`Chromium verification failed for an unrelated reason: ${message}`); + process.exitCode = 1; + } else { + console.log("Chromium rejected the compromised eMudhra certificate"); + } + } finally { + await browser.close(); + } + })().catch((error) => { + console.error(error); + process.exitCode = 1; + }); + NODE + EOF - name: Push tested architecture image uses: docker/build-push-action@v6 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 39be6ca..b494c2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ## [Unreleased] +### 安全与发布 + +- 更新 Go 至 1.26.10,并为 Docker 镜像增加最低 `ca-certificates` / Node.js 安全版本检查,避免继续构建信任已泄露 eMudhra 中间 CA 的旧镜像层。 +- Release 镜像冒烟测试验证 curl 与 Node.js 拒绝使用泄露 CA 签发的证书。 + ## [0.3.18] - 2026-10-12 ### 审批审查 diff --git a/Dockerfile b/Dockerfile index afc096f..a51f845 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,14 +12,34 @@ # docker build -t artex:local . FROM python:3.12-slim-bookworm ARG TARGETARCH +ARG ARTEX_CA_CERTIFICATES_MIN_VERSION=20250419~deb12u2 +ARG ARTEX_NODE_MIN_VERSION=22.23.4 +# Bump this when a security baseline changes so BuildKit cannot reuse an older +# apt layer that predates the baseline. +ARG ARTEX_SECURITY_BASELINE=2026-10-21 # 常用工具:ripgrep / curl / vim,加一批 recon 常备件(按需增删)。 # Node 从 NodeSource 装 22.x,与前端构建使用的主版本一致。 -RUN apt-get update && apt-get install -y --no-install-recommends \ +RUN set -eux; \ + echo "ARTEX_SECURITY_BASELINE=${ARTEX_SECURITY_BASELINE}"; \ + 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/* + 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; \ + ca_version="$(dpkg-query -W -f='${Version}' ca-certificates)"; \ + echo "ca-certificates=${ca_version}"; \ + dpkg --compare-versions "$ca_version" ge "$ARTEX_CA_CERTIFICATES_MIN_VERSION"; \ + node --version; \ + ARTEX_NODE_MIN_VERSION="$ARTEX_NODE_MIN_VERSION" node -e ' \ + const minimum = process.env.ARTEX_NODE_MIN_VERSION.split(".").map(Number); \ + const actual = process.versions.node.split(".").map(Number); \ + for (let i = 0; i < 3; i++) { \ + if (actual[i] > minimum[i]) process.exit(0); \ + if (actual[i] < minimum[i]) process.exit(1); \ + } \ + '; \ + rm -rf /var/lib/apt/lists/* # 预装 Playwright MCP 与 CLI(全局),运行时不再 npx 联网下载。 # @playwright/mcp:browser MCP 直接 `npx @playwright/mcp`(已全局装好,无需 -y/@latest)。 # @playwright/cli:提供 playwright-cli,装完顺带 --help 验证可执行。 diff --git a/go.mod b/go.mod index 35f1a14..ee5f10a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/Autumn-27/artex -go 1.26.3 +go 1.26.10 require ( mvdan.cc/sh/v3 v3.10.0