From 85cabfa142544c61b0c8ea921bb0bcf1ac94c38e Mon Sep 17 00:00:00 2001 From: White-Lotus <95460219+mangyan1@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:57:44 -0600 Subject: [PATCH] adopt anubis 1.28.1 and preserve its challenge assets --- CHANGELOG.md | 2 ++ security-images/anubis/Dockerfile | 30 ++++++++++++++++++------------ security-images/anubis/README.md | 23 +++++++++++++++-------- security-images/anubis/smoke.py | 8 +++++++- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97eeaf0d2e..f17a97fd44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to the NPMplus Security Fork are documented here. The fork u ## Unreleased +- Adopt Anubis 1.28.1 with immutable source/runtime pins and the patched Go networking dependencies. Build its optional WASM and JavaScript fallback assets with pinned Rust tooling, preserve upstream challenge defaults, and verify the embedded baseline/SIMD assets alongside the existing non-root, honeypot and restart contracts. This satisfies the daily scanner's latest-stable compatibility guard and includes upstream's reverse-DNS verification fix. + - Reconcile upstream through October 16: migrate custom locations and their ordered access lists into relational storage, adopt host hard-deletion and mTLS auth-request controls, and update navigation and translations. Keep the fork's session revocation, replay protection, ACL rollback, bounded fetches, setup gate, certificate pipeline, and reviewed dependency versions. Adapt Anubis coverage and ACL recovery to the new relations, with a populated-database upgrade and snapshot regression test. Template version 23 regenerates existing nginx configurations. Database rollback requires restoring the matching pre-upgrade snapshot. - Refresh nginx to 1.31.7 with matching OpenResty patches and njs 1.0.2. Update the Caddy, CrowdSec, and Anubis security builds to Go 1.26.9 and patched networking dependencies; update CrowdSec's OpenAPI parser and Caddy to 2.11.7. Override vulnerable proxy-addr and source-map-js transitive dependencies. Reassess the pinned pip vendor inventory and scope the remaining packaging-tool exceptions to exact package versions until October 23, preserving runtime Certbot DNS-plugin installation. diff --git a/security-images/anubis/Dockerfile b/security-images/anubis/Dockerfile index e4d3b90728..56a70ed364 100644 --- a/security-images/anubis/Dockerfile +++ b/security-images/anubis/Dockerfile @@ -1,36 +1,42 @@ # syntax=docker/dockerfile:1.27.1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e +FROM rust:1.99.0-alpine3.23@sha256:42c2519fdf75d9e34cc61a1aaf34b1a684da9bfd65fe5daefef98d92a801b001 AS rust +RUN rustup target add wasm32-unknown-unknown + FROM golang:1.26.9-alpine3.23@sha256:6750308561953d451210ed1a8086d36c8c8bdcbf672d38d9d0d424b8a7a0216c AS builder -ARG ANUBIS_COMMIT=d39e26cedcc96bea5e4915297c756e7eec74aaf7 -ARG ANUBIS_VERSION=v1.27.0-mangyan1.security.1 +ARG ANUBIS_COMMIT=da1270fcb927e2feac922711f7a5ce54b6a09ef5 +ARG ANUBIS_VERSION=v1.28.1-mangyan1.security.1 ARG X_TEXT_VERSION=v0.42.0 ARG X_NET_VERSION=v0.60.0 -ARG GRPC_VERSION=v1.83.2 -ARG CEL_GO_VERSION=v0.29.2 +ARG GRPC_VERSION=v1.84.0 +ARG CEL_GO_VERSION=v0.32.0 -RUN apk upgrade --no-cache -a && apk add --no-cache nodejs npm bash brotli zstd git make +COPY --from=rust /usr/local/cargo /usr/local/cargo +COPY --from=rust /usr/local/rustup /usr/local/rustup +ENV CARGO_HOME=/usr/local/cargo RUSTUP_HOME=/usr/local/rustup PATH=/usr/local/cargo/bin:$PATH +RUN apk upgrade --no-cache -a && apk add --no-cache nodejs npm bash brotli zstd git make gcc musl-dev WORKDIR /src RUN git init && git remote add origin https://github.com/TecharoHQ/anubis.git && \ git fetch --depth 1 origin "$ANUBIS_COMMIT" && git checkout --detach FETCH_HEAD && \ - git fetch --depth 1 origin refs/tags/v1.27.0:refs/tags/v1.27.0 && \ + git fetch --depth 1 origin refs/tags/v1.28.1:refs/tags/v1.28.1 && \ test "$(git rev-parse HEAD)" = "$ANUBIS_COMMIT" && \ - test "$(git rev-parse 'v1.27.0^{commit}')" = "$ANUBIS_COMMIT" + test "$(git rev-parse 'v1.28.1^{commit}')" = "$ANUBIS_COMMIT" # Preserve the stable application and generated assets; patch its dependencies. RUN go get "golang.org/x/text@$X_TEXT_VERSION" "google.golang.org/grpc@$GRPC_VERSION" \ - "github.com/google/cel-go@$CEL_GO_VERSION" "golang.org/x/net@$X_NET_VERSION" && go mod verify + "cel.dev/cel-go@$CEL_GO_VERSION" "golang.org/x/net@$X_NET_VERSION" && go mod verify RUN npm ci --ignore-scripts && npm run assets -RUN SKIP_INTEGRATION=1 go test ./... && go vet ./... +RUN cargo test --workspace --locked && SKIP_INTEGRATION=1 go test ./... && go vet ./... RUN CGO_ENABLED=0 go build -mod=readonly -trimpath \ -ldflags "-s -w -X github.com/TecharoHQ/anubis.Version=$ANUBIS_VERSION" \ -o /out/anubis ./cmd/anubis # Keep upstream's non-root user, trust store, data, and runtime entrypoint. -FROM ghcr.io/techarohq/anubis:v1.27.0@sha256:8828275668b7bc675679f100970f9714f731388fbbf66ae94de8aca952e3fc4a +FROM ghcr.io/techarohq/anubis:v1.28.1@sha256:1744c03a918160a28b0d2e8c1656de6585f4071b30b4c3b0d51d02282c9b7c25 COPY --from=builder /out/anubis /ko-app/anubis COPY --from=builder /src/LICENSE /licenses/anubis/LICENSE LABEL org.opencontainers.image.source="https://github.com/mangyan1/NPMplus" \ org.opencontainers.image.title="Anubis security build for NPMplus" \ - org.opencontainers.image.version="v1.27.0-mangyan1.security.1" \ + org.opencontainers.image.version="v1.28.1-mangyan1.security.1" \ org.opencontainers.image.licenses="MIT" \ io.npmplus.upstream.source="https://github.com/TecharoHQ/anubis" \ - io.npmplus.upstream.revision="d39e26cedcc96bea5e4915297c756e7eec74aaf7" + io.npmplus.upstream.revision="da1270fcb927e2feac922711f7a5ce54b6a09ef5" diff --git a/security-images/anubis/README.md b/security-images/anubis/README.md index 4e95f98d26..953451a189 100644 --- a/security-images/anubis/README.md +++ b/security-images/anubis/README.md @@ -1,14 +1,16 @@ # Patched Anubis build -This build retains Techaro's Anubis v1.27.0 application and runtime layout while -rebuilding its executable with Go 1.26.8, gRPC 1.83.2, x/text 0.41.0, and CEL -0.29.2. Source and runtime image are pinned to immutable revisions. The upstream -MIT license is included in the final image. +This build retains Techaro's Anubis v1.28.1 application and runtime layout while +rebuilding its executable with Go 1.26.9, gRPC 1.84.0, x/text 0.42.0, x/net 0.60.0, +and cel.dev/cel-go 0.32.0. Source and runtime image are pinned to immutable +revisions. The upstream MIT license is included in the final image. -The generated JavaScript, CSS, localization, and templates are rebuilt using the -upstream lockfile. Upstream unit tests and Go vet run before the executable is -copied into the final image. The runtime retains user 1000, `/ko-app/anubis`, the -trust store, and upstream data. No challenge, honeypot, or policy rule is removed. +The generated JavaScript, CSS, localization, templates, WASM and JavaScript +fallback assets are rebuilt using the upstream lockfiles and a digest-pinned Rust +1.99.0 build stage. Rust tests, upstream Go unit tests and Go vet run before the +executable is copied into the final image. The runtime retains user 1000, +`/ko-app/anubis`, the trust store, and upstream data. No challenge, honeypot, or +policy rule is removed. The Security Images workflow tests and scans both AMD64 and ARM64 candidates before promoting their exact digests to `ghcr.io/mangyan1/npmplus:anubis`. @@ -26,3 +28,8 @@ python3 security-images/anubis/smoke.py npmplus-anubis:check The fork owns updates to these dependency pins and the base image. Reassess the build whenever upstream releases a newer stable version; do not silently combine a new policy document with an older binary. + +Anubis 1.28.1 checks for a 64-byte signing key at startup, including when +`HS512_SECRET` is supplied. Manual deployments using that variable must provide +exactly 64 bytes. The synthetic smoke fixture uses a 64-byte key; the installer +does not set `HS512_SECRET` and keeps upstream's Ed25519 default. diff --git a/security-images/anubis/smoke.py b/security-images/anubis/smoke.py index 103b965a3a..ff5f83d9e0 100644 --- a/security-images/anubis/smoke.py +++ b/security-images/anubis/smoke.py @@ -75,7 +75,7 @@ def main(): "--security-opt", "no-new-privileges", "--tmpfs", "/tmp", "--mount", f"type=volume,source={volume},target=/data", "--mount", f"type=bind,source={policy_path.resolve()},target=/policy.yaml,readonly", - "-e", "HS512_SECRET=npmplus-synthetic-smoke-key-only-20261002", + "-e", "HS512_SECRET=" + "smoke-test-only!" * 4, "-e", "REDIRECT_DOMAINS=example.test", "-p", "127.0.0.1::8923", "-p", "127.0.0.1::9090", image, "--target=", "--policy-fname=/policy.yaml") @@ -103,6 +103,12 @@ def main(): assert status == 401 and b"anubis" in html.lower(), "challenge page missing" status, asset = request(base, "/.within.website/x/cmd/anubis/static/js/main.mjs") assert status == 200 and asset, "embedded challenge JavaScript missing" + for variant in ["baseline", "simd128"]: + for algorithm in ["sha256", "argon2id", "hashx"]: + status, asset = request(base, f"/.within.website/x/cmd/anubis/static/wasm/{variant}/{algorithm}.wasm") + assert status == 200 and asset.startswith(b"\x00asm"), f"missing {variant} {algorithm} WASM asset" + status, asset = request(base, "/.within.website/x/cmd/anubis/static/js/worker/wasm2js.mjs") + assert status == 200 and asset, "embedded JavaScript WASM fallback worker missing" assert request(metrics, "/metrics")[0] == 200, "Prometheus listener missing" print("PASS allow/deny/challenge, embedded assets, metrics", flush=True) assert request(base, "/.within.website/x/cmd/anubis/api/honeypot/smoke/init")[0] == 200