diff --git a/Dockerfile b/Dockerfile index d4203687bbe..b05f07934c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -844,7 +844,7 @@ RUN --network=default set -eu; \ OPENCLAW_LOCK_SHA256=none-legacy-fixture; \ OPENCLAW_RECIPE='ignore-scripts+reviewed-lifecycle-v1'; \ if [ "$OPENCLAW_VERSION" = "2026.7.1" ]; then \ - OPENCLAW_LOCK_SHA256=759b31779f40867f35f15065b582eb1d3efb8fddb1fe43c207507c905fa2a421; \ + OPENCLAW_LOCK_SHA256=a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095; \ ACTUAL_OPENCLAW_LOCK_SHA256="$(sha256sum /usr/local/lib/nemoclaw/openclaw-runtime/package-lock.json | awk '{print $1}')"; \ [ "$ACTUAL_OPENCLAW_LOCK_SHA256" = "$OPENCLAW_LOCK_SHA256" ] \ || { echo "ERROR: OpenClaw lock SHA-256 mismatch (expected $OPENCLAW_LOCK_SHA256, found $ACTUAL_OPENCLAW_LOCK_SHA256)" >&2; exit 1; }; \ @@ -973,7 +973,7 @@ RUN --network=default set -eu; \ npm --prefix /usr/local/lib/nemoclaw/mcporter-runtime ci \ --ignore-scripts --omit=dev --no-audit --no-fund --no-progress; \ npm --prefix /usr/local/lib/nemoclaw/mcporter-runtime ls \ - --omit=dev --all @hono/node-server @modelcontextprotocol/sdk mcporter >/dev/null; \ + --omit=dev --all @hono/node-server @modelcontextprotocol/sdk hono mcporter >/dev/null; \ node --input-type=module -e \ 'const { StreamableHTTPServerTransport } = await import("file:///usr/local/lib/nemoclaw/mcporter-runtime/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js"); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); await transport.close();'; \ ln -s /usr/local/lib/nemoclaw/mcporter-runtime/node_modules/.bin/mcporter /usr/local/bin/mcporter; \ @@ -2384,7 +2384,7 @@ RUN set -eu; \ test "$(stat -c '%u:%g:%a' "$security_inventory")" = "0:0:444"; \ printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ @@ -2395,7 +2395,7 @@ RUN set -eu; \ "perl-base=5.44.0-1nemoclaw1" \ "perl=5.44.0-1nemoclaw1" \ | cmp -s - "$security_inventory"; \ - test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1"; \ + test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1"; \ test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1"; \ test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1"; \ test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1"; \ @@ -2409,7 +2409,7 @@ RUN set -eu; \ ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5'; \ test "$(jq --version)" = "jq-1.8.2"; \ printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null; \ - python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION"; \ + python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION"; \ printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ diff --git a/Dockerfile.base b/Dockerfile.base index 959fb728ce6..f26f315997a 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -107,7 +107,8 @@ ENV AWS_EC2_METADATA_DISABLED=true ENV DEBIAN_FRONTEND=noninteractive # Trixie has not published fixes for the reviewed libexpat, jq, or Vim -# advisories. Install fixed Debian packages from an immutable snapshot, with +# advisories. Install fixed Expat packages from the 20260811T082421Z snapshot +# and fixed jq and Vim packages from the 20260724T000000Z snapshot, with # architecture-specific hashes, until Trixie carries them. # The checksum and runtime probes put the validating command last in each pipe. # The runtime Vim probe verifies the package that this layer installs. @@ -134,14 +135,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && arch="$(dpkg --print-architecture)" \ && case "$arch" in \ amd64) \ - libexpat_sha256="37d24b40a745107941f823d1f22c38f197f01981f7f0783777fe0026af016463"; \ + libexpat_sha256="978e9d30b84893a4c8191d8dae4d1b93c9b7ecaa772ada2fdb892ae3765cab4e"; \ libonig_sha256="3abee130696244050500bcc7870e3b4cb82ddd87149ece3fd55010c3d4e1d18c"; \ libjq_sha256="9a5bf964cef39ed8f0f162e20d856e31961d28a57772b5313989b42a8be7e941"; \ jq_sha256="b973a5d304f666845e8ccefab492e3850d4bc2e7aa2a1e7450862095125f2cc0"; \ vim_tiny_sha256="0e6e231d6d2430a92cf76f8a78506090418fa37758c33b31ed50dfbfc76e22ed" \ ;; \ arm64) \ - libexpat_sha256="df928e3a8e4da79408d4b18e8cd80a03dffa90130d0698e50041aab5e14f9397"; \ + libexpat_sha256="660f5f598a06aa56613a2fbf1ffbd408708175f1a6c2fac833842148f0228176"; \ libonig_sha256="137e708575c0622d347815d19cb471a107546b16e9602805ee27afad7bba107f"; \ libjq_sha256="eae4a828df2eb53d728f88109d9f9549e0983a90b573cf0c7fa1e4bbc7533a7e"; \ jq_sha256="c25086443abd04d1457cbb322a0837f9ba986f82b28f44670467c8dc9be1f696"; \ @@ -152,12 +153,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && perl_version_before="$(dpkg-query -W -f='${Version}' perl)" \ && security_deb_dir="/tmp/nemoclaw-debian-security" \ && snapshot_url="https://snapshot.debian.org/archive/debian/20260724T000000Z/pool/main" \ + && expat_snapshot_url="https://snapshot.debian.org/archive/debian/20260811T082421Z/pool/main" \ && vim_common_sha256="6b063038246492c4a20e0a212c896dde4d5aa9f59d6fb43ff33d10080bc53a39" \ && mkdir -p "$security_deb_dir" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libexpat1.deb" \ - "$snapshot_url/e/expat/libexpat1_2.8.2-1_${arch}.deb" \ + "$expat_snapshot_url/e/expat/libexpat1_2.8.3-1_${arch}.deb" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libonig5.deb" \ @@ -195,7 +197,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ "$security_deb_dir/vim-tiny.deb" \ /tmp/nemoclaw-native-security/libssh2-1t64.deb \ /tmp/nemoclaw-native-security/nemoclaw-python3.13-htmlparser-fix.deb \ - && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1" \ + && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1" \ && test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1" \ && test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1" \ && test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1" \ @@ -207,7 +209,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && test "$(jq --version)" = "jq-1.8.2" \ && ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5' \ && printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null \ - && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION" \ + && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION" \ && printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ @@ -218,7 +220,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && install -d -o root -g root -m 0755 /usr/local/share/nemoclaw \ && printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ @@ -477,7 +479,7 @@ RUN --mount=type=bind,source=nemoclaw-blueprint/blueprint.yaml,target=/tmp/bluep OPENCLAW_LOCK_SHA256=none-legacy-fixture; \ OPENCLAW_RECIPE='ignore-scripts+reviewed-lifecycle-v1'; \ if [ "$OPENCLAW_VERSION" = "2026.7.1" ]; then \ - OPENCLAW_LOCK_SHA256=759b31779f40867f35f15065b582eb1d3efb8fddb1fe43c207507c905fa2a421; \ + OPENCLAW_LOCK_SHA256=a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095; \ ACTUAL_OPENCLAW_LOCK_SHA256="$(sha256sum /usr/local/lib/nemoclaw/openclaw-runtime/package-lock.json | awk '{print $1}')"; \ [ "$ACTUAL_OPENCLAW_LOCK_SHA256" = "$OPENCLAW_LOCK_SHA256" ] \ || { echo "Error: OpenClaw lock SHA-256 mismatch (expected $OPENCLAW_LOCK_SHA256, found $ACTUAL_OPENCLAW_LOCK_SHA256)"; exit 1; }; \ @@ -545,7 +547,7 @@ RUN --mount=type=bind,source=nemoclaw-blueprint/blueprint.yaml,target=/tmp/bluep && npm --prefix /usr/local/lib/nemoclaw/mcporter-runtime ci \ --ignore-scripts --omit=dev --no-audit --no-fund --no-progress \ && npm --prefix /usr/local/lib/nemoclaw/mcporter-runtime ls \ - --omit=dev --all @hono/node-server @modelcontextprotocol/sdk mcporter >/dev/null \ + --omit=dev --all @hono/node-server @modelcontextprotocol/sdk hono mcporter >/dev/null \ && node --input-type=module -e \ 'const { StreamableHTTPServerTransport } = await import("file:///usr/local/lib/nemoclaw/mcporter-runtime/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js"); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); await transport.close();' \ && ln -s /usr/local/lib/nemoclaw/mcporter-runtime/node_modules/.bin/mcporter /usr/local/bin/mcporter \ diff --git a/agents/hermes/Dockerfile b/agents/hermes/Dockerfile index 76d8a4f66f3..7351faf51ac 100644 --- a/agents/hermes/Dockerfile +++ b/agents/hermes/Dockerfile @@ -1274,7 +1274,7 @@ RUN set -eu; \ test "$(stat -c '%u:%g:%a' "$security_inventory")" = "0:0:444"; \ printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ @@ -1285,7 +1285,7 @@ RUN set -eu; \ "perl-base=5.44.0-1nemoclaw1" \ "perl=5.44.0-1nemoclaw1" \ | cmp -s - "$security_inventory"; \ - test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1"; \ + test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1"; \ test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1"; \ test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1"; \ test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1"; \ @@ -1299,7 +1299,7 @@ RUN set -eu; \ ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5'; \ test "$(jq --version)" = "jq-1.8.2"; \ printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null; \ - python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION"; \ + python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION"; \ printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ diff --git a/agents/hermes/Dockerfile.base b/agents/hermes/Dockerfile.base index da4f87957e3..a5dc978dd3d 100644 --- a/agents/hermes/Dockerfile.base +++ b/agents/hermes/Dockerfile.base @@ -81,8 +81,9 @@ ARG UV_VERSION=0.11.33 # build-essential: hermes-agent >= 0.16.0 ships npm dependencies that need a # node-gyp native build during `npm ci`; the runtime Dockerfile purges build # tools again after install. -# Install the reviewed libexpat, jq, and Vim packages from the same immutable, -# checksum-bound Debian snapshot used by the OpenClaw base image. +# Install the reviewed libexpat, jq, and Vim packages from immutable Debian +# snapshots: Expat from 20260811T082421Z and jq and Vim from 20260724T000000Z, +# matching the checksum-bound OpenClaw base image packages. # hadolint ignore=DL3001,DL4006 RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential=12.12 \ @@ -106,14 +107,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && arch="$(dpkg --print-architecture)" \ && case "$arch" in \ amd64) \ - libexpat_sha256="37d24b40a745107941f823d1f22c38f197f01981f7f0783777fe0026af016463"; \ + libexpat_sha256="978e9d30b84893a4c8191d8dae4d1b93c9b7ecaa772ada2fdb892ae3765cab4e"; \ libonig_sha256="3abee130696244050500bcc7870e3b4cb82ddd87149ece3fd55010c3d4e1d18c"; \ libjq_sha256="9a5bf964cef39ed8f0f162e20d856e31961d28a57772b5313989b42a8be7e941"; \ jq_sha256="b973a5d304f666845e8ccefab492e3850d4bc2e7aa2a1e7450862095125f2cc0"; \ vim_tiny_sha256="0e6e231d6d2430a92cf76f8a78506090418fa37758c33b31ed50dfbfc76e22ed" \ ;; \ arm64) \ - libexpat_sha256="df928e3a8e4da79408d4b18e8cd80a03dffa90130d0698e50041aab5e14f9397"; \ + libexpat_sha256="660f5f598a06aa56613a2fbf1ffbd408708175f1a6c2fac833842148f0228176"; \ libonig_sha256="137e708575c0622d347815d19cb471a107546b16e9602805ee27afad7bba107f"; \ libjq_sha256="eae4a828df2eb53d728f88109d9f9549e0983a90b573cf0c7fa1e4bbc7533a7e"; \ jq_sha256="c25086443abd04d1457cbb322a0837f9ba986f82b28f44670467c8dc9be1f696"; \ @@ -123,12 +124,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ esac \ && security_deb_dir="/tmp/nemoclaw-debian-security" \ && snapshot_url="https://snapshot.debian.org/archive/debian/20260724T000000Z/pool/main" \ + && expat_snapshot_url="https://snapshot.debian.org/archive/debian/20260811T082421Z/pool/main" \ && vim_common_sha256="6b063038246492c4a20e0a212c896dde4d5aa9f59d6fb43ff33d10080bc53a39" \ && mkdir -p "$security_deb_dir" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libexpat1.deb" \ - "$snapshot_url/e/expat/libexpat1_2.8.2-1_${arch}.deb" \ + "$expat_snapshot_url/e/expat/libexpat1_2.8.3-1_${arch}.deb" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libonig5.deb" \ @@ -171,7 +173,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ /tmp/nemoclaw-native-security/perl.deb \ && test "$(dpkg-query -W -f='${Version}' perl-base)" = "5.44.0-1nemoclaw1" \ && test "$(dpkg-query -W -f='${Version}' perl)" = "5.44.0-1nemoclaw1" \ - && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1" \ + && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1" \ && test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1" \ && test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1" \ && test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1" \ @@ -182,7 +184,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && test "$(jq --version)" = "jq-1.8.2" \ && ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5' \ && printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null \ - && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION" \ + && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION" \ && printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ @@ -204,7 +206,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && install -d -o root -g root -m 0755 /usr/local/share/nemoclaw \ && printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ diff --git a/agents/langchain-deepagents-code/Dockerfile b/agents/langchain-deepagents-code/Dockerfile index f6f9f9f1d92..ce35f6f800e 100644 --- a/agents/langchain-deepagents-code/Dockerfile +++ b/agents/langchain-deepagents-code/Dockerfile @@ -388,7 +388,7 @@ RUN set -eu; \ test "$(stat -c '%u:%g:%a' "$security_inventory")" = "0:0:444"; \ printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ @@ -399,7 +399,7 @@ RUN set -eu; \ "perl-base=5.44.0-1nemoclaw1" \ "perl=5.44.0-1nemoclaw1" \ | cmp -s - "$security_inventory"; \ - test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1"; \ + test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1"; \ test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1"; \ test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1"; \ test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1"; \ @@ -413,7 +413,7 @@ RUN set -eu; \ ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5'; \ test "$(jq --version)" = "jq-1.8.2"; \ printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null; \ - python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION"; \ + python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION"; \ printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ diff --git a/agents/langchain-deepagents-code/Dockerfile.base b/agents/langchain-deepagents-code/Dockerfile.base index a11bc6bdbd7..05f9ba99131 100644 --- a/agents/langchain-deepagents-code/Dockerfile.base +++ b/agents/langchain-deepagents-code/Dockerfile.base @@ -77,8 +77,9 @@ ENV DEBIAN_FRONTEND=noninteractive \ VIRTUAL_ENV=/opt/venv \ PATH="/usr/local/bin:/opt/venv/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin" -# Install the reviewed libexpat, jq, and Vim packages from the same immutable, -# checksum-bound Debian snapshot used by the OpenClaw base image. +# Install the reviewed libexpat, jq, and Vim packages from immutable Debian +# snapshots: Expat from 20260811T082421Z and jq and Vim from 20260724T000000Z, +# matching the checksum-bound OpenClaw base image packages. # hadolint ignore=DL3001,DL4006 RUN apt-get update && apt-get install -y --no-install-recommends \ python3=3.13.5-1 \ @@ -112,14 +113,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && arch="$(dpkg --print-architecture)" \ && case "$arch" in \ amd64) \ - libexpat_sha256="37d24b40a745107941f823d1f22c38f197f01981f7f0783777fe0026af016463"; \ + libexpat_sha256="978e9d30b84893a4c8191d8dae4d1b93c9b7ecaa772ada2fdb892ae3765cab4e"; \ libonig_sha256="3abee130696244050500bcc7870e3b4cb82ddd87149ece3fd55010c3d4e1d18c"; \ libjq_sha256="9a5bf964cef39ed8f0f162e20d856e31961d28a57772b5313989b42a8be7e941"; \ jq_sha256="b973a5d304f666845e8ccefab492e3850d4bc2e7aa2a1e7450862095125f2cc0"; \ vim_tiny_sha256="0e6e231d6d2430a92cf76f8a78506090418fa37758c33b31ed50dfbfc76e22ed" \ ;; \ arm64) \ - libexpat_sha256="df928e3a8e4da79408d4b18e8cd80a03dffa90130d0698e50041aab5e14f9397"; \ + libexpat_sha256="660f5f598a06aa56613a2fbf1ffbd408708175f1a6c2fac833842148f0228176"; \ libonig_sha256="137e708575c0622d347815d19cb471a107546b16e9602805ee27afad7bba107f"; \ libjq_sha256="eae4a828df2eb53d728f88109d9f9549e0983a90b573cf0c7fa1e4bbc7533a7e"; \ jq_sha256="c25086443abd04d1457cbb322a0837f9ba986f82b28f44670467c8dc9be1f696"; \ @@ -129,12 +130,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ esac \ && security_deb_dir="/tmp/nemoclaw-debian-security" \ && snapshot_url="https://snapshot.debian.org/archive/debian/20260724T000000Z/pool/main" \ + && expat_snapshot_url="https://snapshot.debian.org/archive/debian/20260811T082421Z/pool/main" \ && vim_common_sha256="6b063038246492c4a20e0a212c896dde4d5aa9f59d6fb43ff33d10080bc53a39" \ && mkdir -p "$security_deb_dir" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libexpat1.deb" \ - "$snapshot_url/e/expat/libexpat1_2.8.2-1_${arch}.deb" \ + "$expat_snapshot_url/e/expat/libexpat1_2.8.3-1_${arch}.deb" \ && curl --proto '=https' --tlsv1.2 -fsSL \ --retry 5 --retry-all-errors --retry-delay 2 --connect-timeout 15 --max-time 120 \ -o "$security_deb_dir/libonig5.deb" \ @@ -177,7 +179,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ /tmp/nemoclaw-native-security/perl.deb \ && test "$(dpkg-query -W -f='${Version}' perl-base)" = "5.44.0-1nemoclaw1" \ && test "$(dpkg-query -W -f='${Version}' perl)" = "5.44.0-1nemoclaw1" \ - && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.2-1" \ + && test "$(dpkg-query -W -f='${Version}' libexpat1)" = "2.8.3-1" \ && test "$(dpkg-query -W -f='${Version}' libonig5)" = "6.9.9-1+b1" \ && test "$(dpkg-query -W -f='${Version}' libjq1)" = "1.8.2-1" \ && test "$(dpkg-query -W -f='${Version}' jq)" = "1.8.2-1" \ @@ -188,7 +190,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && test "$(jq --version)" = "jq-1.8.2" \ && ldd /usr/bin/jq | grep -Eq 'libonig[.]so[.]5' \ && printf '%s\n' '{"sandbox":"healthy"}' | jq -e '.sandbox == "healthy"' >/dev/null \ - && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION" \ + && python3 -c "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION" \ && printf '%s %s\n' \ "4ff43a8578bda2f14686c67911b64c18e869841973722b1c623b5727491bdaf7" \ /usr/lib/python3.13/html/parser.py \ @@ -210,7 +212,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && install -d -o root -g root -m 0755 /usr/local/share/nemoclaw \ && printf '%s\n' \ "architecture=$arch" \ - "libexpat1=2.8.2-1" \ + "libexpat1=2.8.3-1" \ "libonig5=6.9.9-1+b1" \ "libjq1=1.8.2-1" \ "jq=1.8.2-1" \ @@ -333,7 +335,7 @@ RUN python3 -m venv --copies "$VIRTUAL_ENV" \ -r /tmp/deepagents-code-requirements.lock \ && "$VIRTUAL_ENV/bin/pip3" check \ && "$VIRTUAL_ENV/bin/python3" -I -c \ - "from importlib.metadata import version; expected = {'aiohttp': '3.14.3', 'cryptography': '50.0.0', 'deepagents-code': '0.1.34', 'mcp': '1.28.1', 'pillow': '12.3.0', 'pyasn1': '0.6.4', 'uv': '0.11.33'}; actual = {name: version(name) for name in expected}; assert actual == expected, actual" \ + "from importlib.metadata import version; expected = {'aiohttp': '3.14.3', 'cryptography': '50.0.0', 'deepagents-code': '0.1.34', 'langgraph-checkpoint-sqlite': '3.1.1', 'mcp': '1.28.1', 'pillow': '12.3.0', 'pyasn1': '0.6.4', 'uv': '0.11.33'}; actual = {name: version(name) for name in expected}; assert actual == expected, actual" \ && ln -sf "$VIRTUAL_ENV/bin/dcode" /usr/local/bin/dcode \ && ln -sf "$VIRTUAL_ENV/bin/deepagents-code" /usr/local/bin/deepagents-code \ && rm -f /tmp/deepagents-code-requirements.lock \ diff --git a/agents/langchain-deepagents-code/dependency-review.md b/agents/langchain-deepagents-code/dependency-review.md index e9f7592d9bc..f8f4262c58c 100644 --- a/agents/langchain-deepagents-code/dependency-review.md +++ b/agents/langchain-deepagents-code/dependency-review.md @@ -7,20 +7,22 @@ This file records the reviewed dependency baseline for the Deep Agents Code sand Update it whenever `requirements.lock` changes. - Lockfile: `agents/langchain-deepagents-code/requirements.lock` -- Lockfile SHA-256: `2e9d59768ea20953c184b52220334e969356ac1a684ff334f0f3767c9f859229` +- Lockfile SHA-256: `56a1c9462b3a68773c7d223457630a52f6b79c35930d5a9212bd42032b7938c6` - Audit command: `uv tool run --python 3.13 pip-audit -r agents/langchain-deepagents-code/requirements.lock --progress-spinner off --disable-pip` -- Audit date: August 3, 2026 -- Targeted audit result: `aiohttp 3.14.3, cryptography 50.0.0, uv 0.11.33, MCP 1.28.1, Pillow 12.3.0, and pyasn1 0.6.4 have no known vulnerabilities` +- Audit date: August 11, 2026 +- Targeted audit result: `aiohttp 3.14.3, cryptography 50.0.0, uv 0.11.33, langgraph-checkpoint-sqlite 3.1.1, MCP 1.28.1, Pillow 12.3.0, and pyasn1 0.6.4 have no known vulnerabilities` - Complete-lock audit result: `2 duplicate records in 1 unrelated package` The Dockerfile installs this lockfile with `pip3 install --require-hashes`, so this review covers the exact package versions selected for the managed image install. -The lock now selects `aiohttp==3.14.3`, `cryptography==50.0.0`, `uv==0.11.33`, `mcp==1.28.1`, `Pillow==12.3.0`, and `pyasn1==0.6.4`. -These selections clear `GHSA-cq5v-8q36-5273` and `GHSA-g6cj-pr64-35w5`. +The lock now selects `aiohttp==3.14.3`, `cryptography==50.0.0`, `uv==0.11.33`, `langgraph-checkpoint-sqlite==3.1.1`, `mcp==1.28.1`, `Pillow==12.3.0`, and `pyasn1==0.6.4`. +These selections clear `GHSA-cq5v-8q36-5273`, `GHSA-g6cj-pr64-35w5`, and `GHSA-47pj-3jcm-6whg`. +The direct `langgraph-checkpoint-sqlite==3.1.1` requirement is a hash-locked security constraint for `GHSA-47pj-3jcm-6whg`. +Remove it when the selected Deep Agents Code graph resolves `3.1.1` or later without the direct constraint and the complete-lock audit remains clear. The direct MCP and pyasn1 requirements are temporary, hash-locked constraints for the released Deep Agents Code `0.1.34` graph. Deep Agents Code `0.1.45` and later contain the MCP and pyasn1 fixes, but their hook boundary has changed. Remove the temporary direct constraints only as part of a separately validated semantic migration to `>=0.1.45` that preserves NemoClaw's managed runtime hooks. -The image build runs `pip3 check` and asserts all seven installed package versions, including Deep Agents Code itself, before publishing. +The image build runs `pip3 check` and asserts all eight installed package versions, including Deep Agents Code itself, before publishing. The complete point-in-time audit now reports only two duplicate database records for `setuptools==82.0.1`; that record is outside the Critical/High remediation scope. This review does not claim the complete lock is vulnerability-free. diff --git a/agents/langchain-deepagents-code/requirements.in b/agents/langchain-deepagents-code/requirements.in index a11a976fda1..bacfee4773e 100644 --- a/agents/langchain-deepagents-code/requirements.in +++ b/agents/langchain-deepagents-code/requirements.in @@ -14,3 +14,5 @@ pillow==12.3.0 mcp==1.28.1 # Fix the transitive ASN.1 decoder resource-exhaustion advisories. pyasn1==0.6.4 +# Fix the transitive SQLite store namespace-prefix matching advisory. +langgraph-checkpoint-sqlite==3.1.1 diff --git a/agents/langchain-deepagents-code/requirements.lock b/agents/langchain-deepagents-code/requirements.lock index 8ab787c012b..0a915e496a2 100644 --- a/agents/langchain-deepagents-code/requirements.lock +++ b/agents/langchain-deepagents-code/requirements.lock @@ -1263,10 +1263,12 @@ langgraph-checkpoint==4.1.1 \ # langgraph-checkpoint-sqlite # langgraph-prebuilt # langgraph-runtime-inmem -langgraph-checkpoint-sqlite==3.1.0 \ - --hash=sha256:cc9b40df0076feae8a9ad42ae713621b148b00ac23adc09dc1dc66090a46e5ad \ - --hash=sha256:f926916ebc1b985d802cc9c820026036e84db9d910d62c97b57e4ba64f67d5ae - # via deepagents-code +langgraph-checkpoint-sqlite==3.1.1 \ + --hash=sha256:6fcb20db4c37ef7aad52f29b539eb98c38e2dad6fab7c2446a2a9db24f37a70e \ + --hash=sha256:8505c54c94a658080525d7e6780fdd4e0c078ff2566b30d399c02cc9f9af1c63 + # via + # -r agents/langchain-deepagents-code/requirements.in + # deepagents-code langgraph-cli==0.4.30 \ --hash=sha256:4948fdc77ff45fc5ef3d8330d17bbecfcb26cd9c4d3a4f00da84a41a0226cd72 \ --hash=sha256:9c577750c57da1a0e3407e8b83e5a0d7eaa80685fe99d95aa7f9bf0e1e73ca92 diff --git a/agents/openclaw/dependency-review.md b/agents/openclaw/dependency-review.md index 392b8d0b6db..cbbf0cb1d35 100644 --- a/agents/openclaw/dependency-review.md +++ b/agents/openclaw/dependency-review.md @@ -16,10 +16,14 @@ Update it and `agents/openclaw/mcporter-runtime/package*.json` together whenever - Locked graph: `agents/openclaw/mcporter-runtime/package-lock.json` (npm lockfile version 3). - Lock regeneration command: `npm --prefix agents/openclaw/mcporter-runtime install --package-lock-only --ignore-scripts --omit=dev` - Advisory command: `npm --prefix agents/openclaw/mcporter-runtime ci --ignore-scripts --omit=dev && node --experimental-strip-types scripts/lib/reviewed-npm-audit.mts --directory agents/openclaw/mcporter-runtime --exceptions ci/npm-audit-exceptions.json --graph mcporter-runtime --threshold high && npm --prefix agents/openclaw/mcporter-runtime audit signatures` -- Advisory review date: 2026-08-03. -- Advisory result: `0` high and `0` critical vulnerabilities across the resolved production dependency graph; the current report keeps `GHSA-8j4g-w8fx-2239` in `hono@4.12.27` visible at moderate severity below the configured threshold. npm verified registry signatures for all `120` resolved packages and attestations for `14` packages. +- Advisory review date: 2026-08-11. +- Advisory result: `0` known vulnerabilities across the resolved production dependency graph. npm verified registry signatures for all `120` resolved packages and attestations for `14` packages. - Security override: `@hono/node-server@2.0.11` (`sha512-bjD221KPLoJTWUwso1J6fGKiTXEUFedG/s0visavY4zakFPkeGURMRNly+FhBHs7T8Dz4qHaZIMX9ZoJHSJtKA==`) replaces the SDK's vulnerable `1.19.14` resolution for `GHSA-frvp-7c67-39w9` and the previously reviewed `2.0.5` resolution affected by `GHSA-9mqv-5hh9-4cgg`. `2.0.5` is the first patched release for `GHSA-frvp-7c67-39w9`. The reviewed v2 range retains the `getRequestListener` API used by `@modelcontextprotocol/sdk`; its Node.js 20 floor is below NemoClaw's Node.js 22.19 floor, and the `/vercel` adapter is not consumed. Mcporter's production path imports the SDK's client transport, not the server adapter, and the image build still exercises the installed CLI after the locked install. Remove the override when the SDK's declared range resolves to a reviewed release outside both affected ranges. - Security override: `fast-uri@3.1.5` (`sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==`) replaces Ajv's vulnerable `3.1.3` resolution and the initially reviewed `3.1.4` remediation. `GHSA-v2hh-gcrm-f6hx` affects releases through `3.1.3`, and `GHSA-7p8r-x3mc-p8w7` affects releases from `3.0.0` through `3.1.4`. The replacement remains within Ajv's declared `^3.0.1` range and preserves the reviewed v3 API boundary. Remove the override when the declared graph resolves to a reviewed release outside both affected ranges. +- Security override: `hono@4.12.34` (`sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==`) replaces the SDK's vulnerable `4.12.27` resolution. + `GHSA-8j4g-w8fx-2239`, `GHSA-54fx-42gc-7vw4`, `GHSA-f23p-vx2j-j53r`, and `GHSA-79qm-7rj5-m7r9` are fixed in `4.12.34`. + The replacement remains within the SDK's declared `^4.11.4` range and preserves Hono's Node.js `>=16.9.0` contract. + Before removing or advancing the override, review the replacement and update the exact-version source-of-truth boundary, lock digests, and regression tests together. - Security override: `ip-address@10.3.1` (`sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==`) replaces `express-rate-limit`'s vulnerable `10.2.0` resolution. `GHSA-mwp4-54f8-5fhr` affects releases through `10.3.0`; the replacement remains within the declared `^10.2.0` range, adds the leading-zero IPv4 rejection and host-only subnet classification required for trust-boundary checks, and preserves Node `>= 12`. Remove the override when the declared graph resolves to a reviewed release outside the affected range. Both image paths install the committed graph with `npm ci --ignore-scripts --omit=dev` because the published package declares no install-time lifecycle script and NemoClaw needs only its already-built CLI. @@ -58,7 +62,7 @@ The lock records the exact version, registry URL, and integrity for every transi ## Source-of-Truth Boundary -- `invalidState`: the image installs a package graph, tarball, license, or advisory state that differs from the independently queried npm registry records for `mcporter@0.7.3`, resolves `@hono/node-server` to any version other than exact `2.0.11`, resolves `fast-uri` to any version other than exact `3.1.5`, or resolves `ip-address` to any version other than exact `10.3.1`. +- `invalidState`: the image installs a package graph, tarball, license, or advisory state that differs from the independently queried npm registry records for `mcporter@0.7.3`, resolves `@hono/node-server` to any version other than exact `2.0.11`, resolves `fast-uri` to any version other than exact `3.1.5`, resolves `hono` to any version other than exact `4.12.34`, or resolves `ip-address` to any version other than exact `10.3.1`. - `sourceBoundary`: npm owns registry metadata, tarball integrity, provenance signatures, and advisory responses; NemoClaw owns the exact lock, script-disabled install, Docker integrity assertion, empty-by-default audit exception registry, and review record. - `whyNotSourceFix`: a repository note cannot make external registry state trustworthy, so image builds execute `npm audit` and `npm audit signatures` against the locked production graph and reviewers compare the lock with the registry response. - `regressionTest`: `test/mcporter-supply-chain.test.ts` keeps the version, integrity, lock metadata, Docker install flags, audit commands, and this review synchronized; `test/reviewed-npm-audit.test.ts` proves exact matching and fail-closed exception validation. diff --git a/agents/openclaw/mcporter-runtime/package-lock.json b/agents/openclaw/mcporter-runtime/package-lock.json index f42f8845d96..8bc6b075ec5 100644 --- a/agents/openclaw/mcporter-runtime/package-lock.json +++ b/agents/openclaw/mcporter-runtime/package-lock.json @@ -970,9 +970,9 @@ } }, "node_modules/hono": { - "version": "4.12.27", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.27.tgz", - "integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==", + "version": "4.12.34", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.34.tgz", + "integrity": "sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==", "license": "MIT", "engines": { "node": ">=16.9.0" diff --git a/agents/openclaw/mcporter-runtime/package.json b/agents/openclaw/mcporter-runtime/package.json index ad6c2fb3b86..60a54035359 100644 --- a/agents/openclaw/mcporter-runtime/package.json +++ b/agents/openclaw/mcporter-runtime/package.json @@ -11,6 +11,7 @@ "overrides": { "@hono/node-server": "2.0.11", "fast-uri": "3.1.5", + "hono": "4.12.34", "ip-address": "10.3.1" }, "engines": { diff --git a/agents/openclaw/openclaw-runtime/package-lock.json b/agents/openclaw/openclaw-runtime/package-lock.json index dc69ae4b3c2..9c1b1f470ad 100644 --- a/agents/openclaw/openclaw-runtime/package-lock.json +++ b/agents/openclaw/openclaw-runtime/package-lock.json @@ -15,6 +15,15 @@ "node": ">=22.22.3 <23 || >=24.15.0 <25 || >=25.9.0" } }, + "node_modules/hono": { + "version": "4.12.34", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.34.tgz", + "integrity": "sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/openclaw": { "version": "2026.7.1", "resolved": "https://registry.npmjs.org/openclaw/-/openclaw-2026.7.1.tgz", @@ -1797,15 +1806,6 @@ "node": ">=12.0.0" } }, - "node_modules/openclaw/node_modules/hono": { - "version": "4.12.25", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.25.tgz", - "integrity": "sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - }, "node_modules/openclaw/node_modules/hosted-git-info": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-10.1.1.tgz", diff --git a/agents/openclaw/openclaw-runtime/package.json b/agents/openclaw/openclaw-runtime/package.json index d651034e53a..3efecf66902 100644 --- a/agents/openclaw/openclaw-runtime/package.json +++ b/agents/openclaw/openclaw-runtime/package.json @@ -8,6 +8,9 @@ "dependencies": { "openclaw": "2026.7.1" }, + "overrides": { + "hono": "4.12.34" + }, "engines": { "node": ">=22.22.3 <23 || >=24.15.0 <25 || >=25.9.0" } diff --git a/ci/reviewed-npm-audit.json b/ci/reviewed-npm-audit.json index 68c30bf827f..cec3e5c5396 100644 --- a/ci/reviewed-npm-audit.json +++ b/ci/reviewed-npm-audit.json @@ -70,8 +70,7 @@ "integrity": "sha512-ge/Xss99CHAjPL/ikmH/UFoiOrjcxDB4sW3y9mhyCD+dYW3wzV7TKbAVdkrXFgAG2d2BjpJofP97zUZ+umxo8g==", "tarballUrl": "https://registry.npmjs.org/openclaw/-/openclaw-2026.7.1.tgz", "directory": "agents/openclaw/openclaw-runtime", - "lockSha256": "759b31779f40867f35f15065b582eb1d3efb8fddb1fe43c207507c905fa2a421", - "replacementLockSha256": "a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095" + "lockSha256": "a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095" }, { "id": "mcporter-runtime", @@ -80,8 +79,7 @@ "integrity": "sha512-egoPVYqTnWb3NjRIxo+xc8OrAI0dlPrJm9pAiZx0pImuNIV5rKhGtTnIfH/Y1ldGPVu74ibj3KR5c9U/QSdQFA==", "tarballUrl": "https://registry.npmjs.org/mcporter/-/mcporter-0.7.3.tgz", "directory": "agents/openclaw/mcporter-runtime", - "lockSha256": "962dee34f6b0a493521d1619d1cf030e2630cbdfce8bf0598217202f57078793", - "replacementLockSha256": "17f2372a0a6949df928333a2f98862ae563013a7682b19a8ce63825c4696a064" + "lockSha256": "17f2372a0a6949df928333a2f98862ae563013a7682b19a8ce63825c4696a064" }, { "id": "mcp-tool-discovery-runtime", diff --git a/docs/security/openclaw-2026.7.1-dependency-review.md b/docs/security/openclaw-2026.7.1-dependency-review.md index 3806e48d720..8fa38c118a7 100644 --- a/docs/security/openclaw-2026.7.1-dependency-review.md +++ b/docs/security/openclaw-2026.7.1-dependency-review.md @@ -19,7 +19,7 @@ the exact plugin graph reports no vulnerabilities after that update. The production OpenClaw install uses the authoritative committed lock at `agents/openclaw/openclaw-runtime/package-lock.json`, with SHA-256 -`759b31779f40867f35f15065b582eb1d3efb8fddb1fe43c207507c905fa2a421`. +`a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095`. NemoClaw derives that lock from the SRI-verified `openclaw@2026.7.1` archive after applying the reviewed dependency remediation. The remediation replaces `brace-expansion@5.0.7` with `5.0.9`. @@ -29,6 +29,7 @@ The same reviewed `undici@8.10.0` replacement applies to the OpenClaw core dependency and the Discord manifest, shrinkwrap, and bundled package tree. The committed mcporter lock also selects `fast-uri@3.1.5` and `ip-address@10.3.1`. +Both committed runtime locks select `hono@4.12.34`. Image builds verify the lock digest and installed production graph before they expose the OpenClaw binary. @@ -87,8 +88,12 @@ whose amd64 config reports Node `22.23.1`. - `https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz` - `MIT`; no dependencies; Node `>= 12` - annotated source tag commit: `be7e626c0d49fccb518899f520a3fb64ee189741`; unsigned tag +- `hono@4.12.34` (OpenClaw and mcporter locked-runtime remediation) + - `sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==` + - `https://registry.npmjs.org/hono/-/hono-4.12.34.tgz` + - `MIT`; no dependencies; Node.js `>=16.9.0` - `mcporter@0.7.3` committed runtime lock - - SHA-256: `962dee34f6b0a493521d1619d1cf030e2630cbdfce8bf0598217202f57078793` + - SHA-256: `17f2372a0a6949df928333a2f98862ae563013a7682b19a8ce63825c4696a064` `fast-uri@3.1.5` has a valid npm registry signature and no registry attestation. `undici@8.10.0` has a valid npm registry signature and SLSA provenance. @@ -104,9 +109,9 @@ Its exact results are: - Reviewed archive graph: `info=0`, `low=0`, `moderate=6`, `high=0`, `critical=0`, `clean`. -- OpenClaw locked runtime: `info=0`, `low=0`, `moderate=7`, `high=0`, +- OpenClaw locked runtime: `info=0`, `low=0`, `moderate=6`, `high=0`, `critical=0`, `clean`. -- mcporter runtime: `info=0`, `low=0`, `moderate=1`, `high=0`, `critical=0`, +- mcporter runtime: `info=0`, `low=0`, `moderate=0`, `high=0`, `critical=0`, `clean`. Registry signature checks completed within the successful audit. @@ -130,6 +135,14 @@ requirement remains inside the image's Node contract, and real ESM plus CommonJS Streamable HTTP transport construction/start/close probes cover the major-version compatibility boundary. +The SDK graphs in OpenClaw and mcporter request `hono@^4.11.4`. +The committed locks previously selected `4.12.25` and `4.12.27`. +`GHSA-8j4g-w8fx-2239`, `GHSA-54fx-42gc-7vw4`, +`GHSA-f23p-vx2j-j53r`, and `GHSA-79qm-7rj5-m7r9` affect those releases. +Version `4.12.34` fixes all four advisories. +Both runtime manifests now select reviewed `4.12.34` through an exact override +that remains within the declared SDK range. + OpenClaw's `minimatch@10.2.5` edge originally resolved `brace-expansion@5.0.7`, which is affected by `GHSA-mh99-v99m-4gvg`. The initial remediation selected `5.0.8` for that advisory. diff --git a/docs/security/sandbox-base-2026-07-25-dependency-review.md b/docs/security/sandbox-base-2026-07-25-dependency-review.md index e57b1223fe4..e049edc2d27 100644 --- a/docs/security/sandbox-base-2026-07-25-dependency-review.md +++ b/docs/security/sandbox-base-2026-07-25-dependency-review.md @@ -5,17 +5,17 @@ Date: 2026-07-25 -Last updated: August 8, 2026 +Last updated: August 11, 2026 ## Scope This review covers the sandbox dependency changes that: -- standardize the OpenClaw, Hermes, and Deep Agents Code base images on fixed Debian `libexpat1=2.8.2-1`, `libjq1=1.8.2-1`, `jq=1.8.2-1`, `vim-common=2:9.2.0782-1`, and `vim-tiny=2:9.2.0782-1` packages, with the reviewed `libonig5=6.9.9-1+b1` jq runtime dependency; +- standardize the OpenClaw, Hermes, and Deep Agents Code base images on fixed Debian `libexpat1=2.8.3-1`, `libjq1=1.8.2-1`, `jq=1.8.2-1`, `vim-common=2:9.2.0782-1`, and `vim-tiny=2:9.2.0782-1` packages, with the reviewed `libonig5=6.9.9-1+b1` jq runtime dependency; - replace the `brace-expansion@5.0.7` copy inside the reviewed `npm@11.18.0` package with `brace-expansion@5.0.9`; and - verify the security-relevant dual-life module versions shipped by the checksum-pinned Perl 5.44.0 build. -The OpenClaw base image retains its existing reviewed jq and Expat identities, while the Hermes and Deep Agents Code base images move to the same package boundary. +All three managed base images now share the same reviewed jq and Expat identities. These changes preserve the existing supported image behavior and do not create a new integration or product surface. ## Release and artifact identities @@ -25,7 +25,7 @@ These changes preserve the existing supported image behavior and do not create a | Vim | All managed images: Debian trixie `2:9.1.1230-2` | Debian sid `2:9.2.0782-1` | Debian Snapshot `20260724T000000Z` and package SHA-256 values below | | jq | OpenClaw: `1.8.2-1`; Hermes and Deep Agents Code: `1.7.1-6+deb13u2` | All managed images: `libjq1=1.8.2-1` and `jq=1.8.2-1` | Debian Snapshot `20260724T000000Z` and architecture-specific SHA-256 values below | | Oniguruma | Distro-selected jq runtime dependency | All managed images: `libonig5=6.9.9-1+b1` | Debian Snapshot `20260724T000000Z` and architecture-specific SHA-256 values below | -| Expat | OpenClaw: `2.8.2-1`; Hermes and Deep Agents Code: distro-selected package | All managed images: `libexpat1=2.8.2-1` | Debian Snapshot `20260724T000000Z` and architecture-specific SHA-256 values below | +| Expat | All managed images: `2.8.2-1` | All managed images: `libexpat1=2.8.3-1` | Debian Snapshot `20260811T082421Z` and architecture-specific SHA-256 values below | | npm | `npm@11.18.0` | unchanged | Existing reviewed npm archive and integrity | | npm private `brace-expansion` | `5.0.7` | `5.0.9` | Registry tarball and SHA-512 integrity below | | Perl | `5.44.0-1nemoclaw1` | unchanged | Existing CPAN archive SHA-256 and complete upstream test suite | @@ -37,7 +37,7 @@ The immutable Debian package SHA-256 values are: | Package | amd64 | arm64 | | --- | --- | --- | -| `libexpat1_2.8.2-1` | `37d24b40a745107941f823d1f22c38f197f01981f7f0783777fe0026af016463` | `df928e3a8e4da79408d4b18e8cd80a03dffa90130d0698e50041aab5e14f9397` | +| `libexpat1_2.8.3-1` | `978e9d30b84893a4c8191d8dae4d1b93c9b7ecaa772ada2fdb892ae3765cab4e` | `660f5f598a06aa56613a2fbf1ffbd408708175f1a6c2fac833842148f0228176` | | `libonig5_6.9.9-1+b1` | `3abee130696244050500bcc7870e3b4cb82ddd87149ece3fd55010c3d4e1d18c` | `137e708575c0622d347815d19cb471a107546b16e9602805ee27afad7bba107f` | | `libjq1_1.8.2-1` | `9a5bf964cef39ed8f0f162e20d856e31961d28a57772b5313989b42a8be7e941` | `eae4a828df2eb53d728f88109d9f9549e0983a90b573cf0c7fa1e4bbc7533a7e` | | `jq_1.8.2-1` | `b973a5d304f666845e8ccefab492e3850d4bc2e7aa2a1e7450862095125f2cc0` | `c25086443abd04d1457cbb322a0837f9ba986f82b28f44670467c8dc9be1f696` | @@ -54,7 +54,8 @@ The reviewed npm replacement is: ### Managed-image Debian package compatibility -Each managed base image downloads the six exact Debian packages from the same immutable snapshot and verifies every package checksum before installation. +Each managed base image downloads Expat from Debian Snapshot `20260811T082421Z` and the other five exact Debian packages from Snapshot `20260724T000000Z`. +The image verifies every package checksum before installation. Each image installs the complete jq runtime closure and matching Vim package pair together, verifies every dpkg identity, confirms that jq links to `libonig.so.5`, exercises jq and Python Expat, and verifies that the Vim runtime reports version 9.2. The package architecture is selected from `dpkg --print-architecture`, and any architecture other than amd64 or arm64 fails closed. The base writes that architecture and the six exact package identities to a root-owned, read-only inventory. @@ -76,7 +77,7 @@ The final reviewed dependency set and range evidence is: | Package or component | Previous or affected boundary | Final reviewed boundary | Runtime and inventory proof | | --- | --- | --- | --- | -| `libexpat1` | distro-selected package or `2.8.2-1` | `2.8.2-1` | exact dpkg identity and Python `pyexpat` reports Expat 2.8.2 | +| `libexpat1` | `2.8.2-1`, affected by `CVE-2026-72522` | `2.8.3-1` | exact dpkg identity and Python `pyexpat` reports Expat 2.8.3 | | `libonig5` | jq dependency floor `>= 6.9.7.1` | `6.9.9-1+b1` | exact dpkg identity and `/usr/bin/jq` links to `libonig.so.5` | | `libjq1` | `1.7.1-6+deb13u2..1.8.2-1` | `1.8.2-1` | exact dpkg identity and matching `jq` runtime | | `jq` | `1.7.1-6+deb13u2..1.8.2-1` | `1.8.2-1` | exact dpkg identity, `jq-1.8.2`, and a JSON expression probe | @@ -168,21 +169,21 @@ The core interpreter version check also remains the binding for core-language fi - Verification: native amd64 and arm64 image builds. - Remaining gate: multi-architecture base-image build. -### DEP-4 managed jq, Oniguruma, and Expat identities differ +### DEP-4 managed jq, Oniguruma, and Expat identities differ or are outdated -- Range: `libexpat1` distro-selected or `2.8.2-1` to `2.8.2-1`; `libjq1` and `jq` `1.7.1-6+deb13u2..1.8.2-1`; `libonig5 >= 6.9.7.1` to exact `6.9.9-1+b1`. +- Range: `libexpat1` distro-selected or `2.8.2-1` to `2.8.3-1`; `libjq1` and `jq` `1.7.1-6+deb13u2..1.8.2-1`; `libonig5 >= 6.9.7.1` to exact `6.9.9-1+b1`. - Surface: native packages and runtime libraries -- Severity: high +- Severity: high for the jq boundary and medium for `CVE-2026-72522` - Confidence: high - Failure mode: a managed image can retain an older jq or Expat runtime, or fail to configure jq when its architecture-specific Oniguruma dependency is absent. - Disposition: migrate, pin, test, runtime-proof -- Implementation: use the same snapshot, architecture-specific checksums, dpkg identities, and runtime guards in every managed base image. +- Implementation: use the same Expat snapshot and the same existing jq/Vim snapshot, architecture-specific checksums, dpkg identities, and runtime guards in every managed base image. - Verification: exact base-package and completed-image `RUN`-chain execution, immutable inventory content and metadata checks, checksum-rejection tests, installed dpkg identities, runtime probes, and empty dpkg audit for all three images on amd64 and arm64. - Remaining gate: multi-image, multi-architecture CI. ## Removal conditions -Remove the Debian snapshot override only when the supported Debian suite publishes packages at or beyond every reviewed fix boundary and the replacements pass the same amd64 and arm64 package and runtime checks for all managed base images. +Remove either Debian snapshot override only when the supported Debian suite publishes packages at or beyond its reviewed fix boundary and the replacements pass the same amd64 and arm64 package and runtime checks for all managed base images. Remove the private brace-expansion helper only when every pinned Node base installs a reviewed npm release whose complete private tree contains no brace-expansion version below 5.0.9. Updating the npm archive without revisiting this helper must fail the image contract. diff --git a/src/lib/onboard/dockerfile-remote-dashboard-bind-contract.ts b/src/lib/onboard/dockerfile-remote-dashboard-bind-contract.ts index 842a69a6e16..c72bce6f14a 100644 --- a/src/lib/onboard/dockerfile-remote-dashboard-bind-contract.ts +++ b/src/lib/onboard/dockerfile-remote-dashboard-bind-contract.ts @@ -37,7 +37,7 @@ const CANONICAL_POST_GENERATOR_RUN_SHA256 = new Set([ "6f457f365f5c0d128e5e3b549a630b5bd9ebd223919f2c2c8e6a31235d763781", "dca7d3dbc030e4efa77c850b9d21a826358c69c7d2062f3eee2f5a57eeb07aa2", "b01b5f5d2cba5778cd8eb87139f2c6a8174082a7f6775e443a1dbdc0629ce7e5", - "4a54da2c1c33c681ae0dad181a5a7456c926051d91420aa60cf7edef6330ba65", + "4a48c125d519e3967d4dfc45bb9970ab1a7ba60336854cc4aed03cde81336f88", "e7256f12c618bb424f53fec801378d92446d880c5935965ebb3b548694866b63", "4e548aafe9484a887a0ab0cf92ec82f77843fd346de7a2dff50b93ebd632b044", "737edaaa69f80cf10d42fd349e0be068c1ef6e7375d5dcb4055b012420b58736", diff --git a/src/lib/sandbox-base-image/security-inventory.ts b/src/lib/sandbox-base-image/security-inventory.ts index 212cd9b04a4..c107878ecdc 100644 --- a/src/lib/sandbox-base-image/security-inventory.ts +++ b/src/lib/sandbox-base-image/security-inventory.ts @@ -6,7 +6,7 @@ import { dockerCapture } from "../adapters/docker"; const SECURITY_INVENTORY_PROBE_OK = "nemoclaw-security-inventory-ok"; export const SANDBOX_BASE_SECURITY_PACKAGE_INVENTORY = [ - "libexpat1=2.8.2-1", + "libexpat1=2.8.3-1", "libonig5=6.9.9-1+b1", "libjq1=1.8.2-1", "jq=1.8.2-1", diff --git a/test/helpers/base-apt-security-functions.ts b/test/helpers/base-apt-security-functions.ts index a0166bff54f..3d83ea313bc 100644 --- a/test/helpers/base-apt-security-functions.ts +++ b/test/helpers/base-apt-security-functions.ts @@ -8,14 +8,14 @@ export const BASE_APT_SECURITY_HASHES: Record< { libexpat: string; libonig: string; libjq: string; jq: string; vimTiny: string } > = { amd64: { - libexpat: "37d24b40a745107941f823d1f22c38f197f01981f7f0783777fe0026af016463", + libexpat: "978e9d30b84893a4c8191d8dae4d1b93c9b7ecaa772ada2fdb892ae3765cab4e", libonig: "3abee130696244050500bcc7870e3b4cb82ddd87149ece3fd55010c3d4e1d18c", libjq: "9a5bf964cef39ed8f0f162e20d856e31961d28a57772b5313989b42a8be7e941", jq: "b973a5d304f666845e8ccefab492e3850d4bc2e7aa2a1e7450862095125f2cc0", vimTiny: "0e6e231d6d2430a92cf76f8a78506090418fa37758c33b31ed50dfbfc76e22ed", }, arm64: { - libexpat: "df928e3a8e4da79408d4b18e8cd80a03dffa90130d0698e50041aab5e14f9397", + libexpat: "660f5f598a06aa56613a2fbf1ffbd408708175f1a6c2fac833842148f0228176", libonig: "137e708575c0622d347815d19cb471a107546b16e9602805ee27afad7bba107f", libjq: "eae4a828df2eb53d728f88109d9f9549e0983a90b573cf0c7fa1e4bbc7533a7e", jq: "c25086443abd04d1457cbb322a0837f9ba986f82b28f44670467c8dc9be1f696", @@ -44,7 +44,7 @@ export function baseAptSecurityFunctions(architecture: DebianArchitecture): stri "dpkg-query() {", ' [[ "$#" -eq 3 && "$1" == "-W" && "$2" == \'-f=${Version}\' ]] || return 64', ' case "$3" in', - ' libexpat1) printf "2.8.2-1" ;;', + ' libexpat1) printf "2.8.3-1" ;;', ' libonig5) printf "6.9.9-1+b1" ;;', ' libjq1|jq) printf "1.8.2-1" ;;', ' perl-base) [[ "${perl_base_installed:-0}" == "1" ]] || return 64; printf "5.44.0-1nemoclaw1" ;;', @@ -62,7 +62,7 @@ export function baseAptSecurityFunctions(architecture: DebianArchitecture): stri ' [[ "$5" == "--retry" && "$6" == "5" && "$7" == "--retry-all-errors" && "$8" == "--retry-delay" && "$9" == "2" ]] || return 64', ' [[ "${10}" == "--connect-timeout" && "${11}" == "15" && "${12}" == "--max-time" && "${13}" == "120" && "${14}" == "-o" ]] || return 64', ' case "${16}" in', - ` */e/expat/libexpat1_2.8.2-1_${architecture}.deb) [[ "\${15##*/}" == "libexpat1.deb" ]] ;;`, + ` */e/expat/libexpat1_2.8.3-1_${architecture}.deb) [[ "\${15##*/}" == "libexpat1.deb" ]] ;;`, ` */libo/libonig/libonig5_6.9.9-1+b1_${architecture}.deb) [[ "\${15##*/}" == "libonig5.deb" ]] ;;`, ` */j/jq/libjq1_1.8.2-1_${architecture}.deb) [[ "\${15##*/}" == "libjq1.deb" ]] ;;`, ` */j/jq/jq_1.8.2-1_${architecture}.deb) [[ "\${15##*/}" == "jq.deb" ]] ;;`, @@ -119,7 +119,7 @@ export function baseAptSecurityFunctions(architecture: DebianArchitecture): stri "python3() {", ' [[ "$#" -eq 2 && "$1" == "-c" ]] || return 64', ' case "$2" in', - " \"import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION\") ;;", + " \"import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION\") ;;", " \"import sys; from pathlib import Path; import html.parser; Path(html.parser.__file__).resolve() == Path('/usr/lib/python3.13/html/parser.py').resolve() or sys.exit('html.parser loaded from an unexpected path'); from html.parser import HTMLParser; p=HTMLParser(); [p.feed('') for _ in range(20000)]; p._pending == [] or sys.exit('empty feeds accumulated pending entries'); p.feed(''); p.close(); p.rawdata == '' or sys.exit('incremental parsing retained raw data')\") ;;", " \"import ctypes, sys; lib=ctypes.CDLL('libssh2.so.1'); lib.libssh2_version.restype=ctypes.c_char_p; lib.libssh2_version(0) == b'1.11.1' or sys.exit('unexpected libssh2 runtime version')\") ;;", " *) return 64 ;;", diff --git a/test/helpers/onboard-script-mocks.cjs b/test/helpers/onboard-script-mocks.cjs index f156b6b09a4..d938ce338b8 100644 --- a/test/helpers/onboard-script-mocks.cjs +++ b/test/helpers/onboard-script-mocks.cjs @@ -71,7 +71,7 @@ const OPENCLAW_SECURITY_INVENTORY_PROBE = [ 'test -f "$security_inventory"', 'test ! -L "$security_inventory"', `test "$(stat -c '%u:%g:%a' "$security_inventory")" = "0:0:444"`, - `printf '%s\\n' "architecture=$arch" "libexpat1=2.8.2-1" "libonig5=6.9.9-1+b1" "libjq1=1.8.2-1" "jq=1.8.2-1" "vim-common=2:9.2.0782-1" "vim-tiny=2:9.2.0782-1" "libssh2-1t64=1.11.1-1+deb13u1+nemoclaw1" "nemoclaw-python3.13-htmlparser-fix=3.13.5-2+deb13u4+nemoclaw1" "perl-base=5.44.0-1nemoclaw1" "perl=5.44.0-1nemoclaw1" | cmp -s - "$security_inventory"`, + `printf '%s\\n' "architecture=$arch" "libexpat1=2.8.3-1" "libonig5=6.9.9-1+b1" "libjq1=1.8.2-1" "jq=1.8.2-1" "vim-common=2:9.2.0782-1" "vim-tiny=2:9.2.0782-1" "libssh2-1t64=1.11.1-1+deb13u1+nemoclaw1" "nemoclaw-python3.13-htmlparser-fix=3.13.5-2+deb13u4+nemoclaw1" "perl-base=5.44.0-1nemoclaw1" "perl=5.44.0-1nemoclaw1" | cmp -s - "$security_inventory"`, `printf '%s\\n' "nemoclaw-security-inventory-ok"`, ].join("; "); diff --git a/test/helpers/python-parser-security-fixture.ts b/test/helpers/python-parser-security-fixture.ts index 4965c0c2519..0aa3d19b63d 100644 --- a/test/helpers/python-parser-security-fixture.ts +++ b/test/helpers/python-parser-security-fixture.ts @@ -13,7 +13,7 @@ export function htmlParserSecurityProbe(parserPath: string): string { } const PYEXPAT_PROBE = - "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.2', pyexpat.EXPAT_VERSION"; + "import pyexpat; assert pyexpat.EXPAT_VERSION == 'expat_2.8.3', pyexpat.EXPAT_VERSION"; const LIBSSH2_PROBE = "import ctypes, sys; lib=ctypes.CDLL('libssh2.so.1'); lib.libssh2_version.restype=ctypes.c_char_p; lib.libssh2_version(0) == b'1.11.1' or sys.exit('unexpected libssh2 runtime version')"; const FIXED_PARSER_FIXTURE = path.resolve( diff --git a/test/langchain-deepagents-code-image.test.ts b/test/langchain-deepagents-code-image.test.ts index c3e432f0f92..ca307d0ad34 100644 --- a/test/langchain-deepagents-code-image.test.ts +++ b/test/langchain-deepagents-code-image.test.ts @@ -1077,7 +1077,7 @@ describe("LangChain Deep Agents Code image contracts", () => { "uv tool run --python 3.13 pip-audit -r agents/langchain-deepagents-code/requirements.lock --progress-spinner off --disable-pip", ); expect(review).toContain( - "Targeted audit result: `aiohttp 3.14.3, cryptography 50.0.0, uv 0.11.33, MCP 1.28.1, Pillow 12.3.0, and pyasn1 0.6.4 have no known vulnerabilities`", + "Targeted audit result: `aiohttp 3.14.3, cryptography 50.0.0, uv 0.11.33, langgraph-checkpoint-sqlite 3.1.1, MCP 1.28.1, Pillow 12.3.0, and pyasn1 0.6.4 have no known vulnerabilities`", ); expect(review).toContain( "Complete-lock audit result: `2 duplicate records in 1 unrelated package`", @@ -1094,11 +1094,13 @@ describe("LangChain Deep Agents Code image contracts", () => { expect(requirementsLock).toContain("mcp==1.28.1"); expect(requirementsLock).toContain("pillow==12.3.0"); expect(requirementsLock).toContain("pyasn1==0.6.4"); + expect(requirementsLock).toContain("langgraph-checkpoint-sqlite==3.1.1"); const dockerfileBase = readAgentFile("Dockerfile.base"); for (const [name, expectedVersion] of [ ["aiohttp", "3.14.3"], ["cryptography", "50.0.0"], ["deepagents-code", "0.1.34"], + ["langgraph-checkpoint-sqlite", "3.1.1"], ] as const) { expect(dockerfileBase).toContain(`'${name}': '${expectedVersion}'`); } diff --git a/test/mcporter-supply-chain.test.ts b/test/mcporter-supply-chain.test.ts index 516825e9e69..07e6a1e4de1 100644 --- a/test/mcporter-supply-chain.test.ts +++ b/test/mcporter-supply-chain.test.ts @@ -25,6 +25,8 @@ const expectedTarball = "https://registry.npmjs.org/mcporter/-/mcporter-0.7.3.tg const expectedHonoNodeServerVersion = "2.0.11"; const expectedHonoNodeServerTarball = "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.11.tgz"; +const expectedHonoVersion = "4.12.34"; +const expectedHonoTarball = "https://registry.npmjs.org/hono/-/hono-4.12.34.tgz"; const expectedFastUriVersion = "3.1.5"; const expectedFastUriTarball = "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz"; const expectedIpAddressVersion = "10.3.1"; @@ -86,6 +88,9 @@ describe("mcporter image supply-chain controls", () => { expect(dependencyReview).toContain("`GHSA-v2hh-gcrm-f6hx`"); expect(dependencyReview).toContain("`GHSA-7p8r-x3mc-p8w7`"); expect(dependencyReview).toContain("exact `3.1.5`"); + expect(dependencyReview).toContain("`hono@4.12.34`"); + expect(dependencyReview).toContain("`GHSA-54fx-42gc-7vw4`"); + expect(dependencyReview).toContain("exact `4.12.34`"); expect(dependencyReview).toContain("`ip-address@10.3.1`"); expect(dependencyReview).toContain("`GHSA-mwp4-54f8-5fhr`"); expect(dependencyReview).toContain("exact `10.3.1`"); @@ -108,6 +113,13 @@ describe("mcporter image supply-chain controls", () => { version: expectedHonoNodeServerVersion, }), ); + expect(findDependency(graph, "hono")).toEqual( + expect.objectContaining({ + overridden: true, + resolved: expectedHonoTarball, + version: expectedHonoVersion, + }), + ); expect(findDependency(graph, "fast-uri")).toEqual( expect.objectContaining({ overridden: true, @@ -187,7 +199,7 @@ describe("mcporter image supply-chain controls", () => { expect(contents).not.toContain(`${runtimePrefix} audit --omit=dev --audit-level=low`); expect(contents).toContain(`${runtimePrefix} audit signatures`); expect(flattenedContents).toContain( - `${runtimePrefix} ls --omit=dev --all @hono/node-server @modelcontextprotocol/sdk mcporter`, + `${runtimePrefix} ls --omit=dev --all @hono/node-server @modelcontextprotocol/sdk hono mcporter`, ); expect(contents).toContain("StreamableHTTPServerTransport"); }); diff --git a/test/openclaw-dependency-review.test.ts b/test/openclaw-dependency-review.test.ts index 06b2c632109..e92092f430f 100644 --- a/test/openclaw-dependency-review.test.ts +++ b/test/openclaw-dependency-review.test.ts @@ -282,6 +282,10 @@ describe("OpenClaw 2026.6.10 dependency review contract", () => { expect(review).toContain("GHSA-mwp4-54f8-5fhr"); expect(review).toContain("ip-address@^10.2.0"); expect(review).toContain("ip-address@10.3.1"); + expect(review).toContain("hono@4.12.34"); + expect(review).toContain("GHSA-54fx-42gc-7vw4"); + expect(review).toContain("GHSA-f23p-vx2j-j53r"); + expect(review).toContain("GHSA-79qm-7rj5-m7r9"); }); it("keeps advisor disposition evidence in the dependency review note", () => { diff --git a/test/openclaw-locked-install.test.ts b/test/openclaw-locked-install.test.ts index 1fc9a6a3db2..f211e95d85b 100644 --- a/test/openclaw-locked-install.test.ts +++ b/test/openclaw-locked-install.test.ts @@ -19,9 +19,8 @@ const PACKAGE_SPEC = "openclaw@2026.7.1"; const INTEGRITY = "sha512-ge/Xss99CHAjPL/ikmH/UFoiOrjcxDB4sW3y9mhyCD+dYW3wzV7TKbAVdkrXFgAG2d2BjpJofP97zUZ+umxo8g=="; const TARBALL = "https://registry.npmjs.org/openclaw/-/openclaw-2026.7.1.tgz"; -const LOCK_SHA256 = "759b31779f40867f35f15065b582eb1d3efb8fddb1fe43c207507c905fa2a421"; +const LOCK_SHA256 = "a814d82a36046bd7819d222337809ce80ccfd76b553cd17265ff64a527d3d095"; const MCPORTER_PACKAGE_SPEC = "mcporter@0.7.3"; -const MCPORTER_LOCK_SHA256 = "962dee34f6b0a493521d1619d1cf030e2630cbdfce8bf0598217202f57078793"; const MCP_TOOL_DISCOVERY_PACKAGE_SPEC = "@modelcontextprotocol/sdk@1.30.0"; const MCP_TOOL_DISCOVERY_LOCK_SHA256 = "bc7e34d9eb1f72cf3016c8b88c72d3b7682a4f234903cb93b9476b10d7e954eb"; @@ -179,6 +178,7 @@ describe("locked OpenClaw production installation (#5896)", () => { expect(verified).toContain(PACKAGE_SPEC); expect(verified).toContain("brace-expansion@5.0.9"); expect(verified).toContain("fast-uri@3.1.5"); + expect(verified).toContain("hono@4.12.34"); expect(verified).toContain("ip-address@10.3.1"); expect(verified).toContain("undici@8.10.0"); expect(sha256(LOCKFILE)).toBe(LOCK_SHA256); diff --git a/test/sandbox-base-security-packages.test.ts b/test/sandbox-base-security-packages.test.ts index 34f77a2557d..64582b84153 100644 --- a/test/sandbox-base-security-packages.test.ts +++ b/test/sandbox-base-security-packages.test.ts @@ -43,7 +43,7 @@ const SECURITY_IMAGES = [ ] as const; const ARCHITECTURES = ["amd64", "arm64"] as const; const EXPECTED_SECURITY_PACKAGE_INVENTORY = [ - "libexpat1=2.8.2-1", + "libexpat1=2.8.3-1", "libonig5=6.9.9-1+b1", "libjq1=1.8.2-1", "jq=1.8.2-1", @@ -157,6 +157,9 @@ describe("sandbox base security packages", () => { ); expect({ status: result.status, stderr: result.stderr }).toEqual({ status: 0, stderr: "" }); expect(calls).toContain("dpkg-install"); + expect(calls).toContain( + `download https://snapshot.debian.org/archive/debian/20260811T082421Z/pool/main/e/expat/libexpat1_2.8.3-1_${architecture}.deb`, + ); expect(fs.readFileSync(prepared.inventory, "utf-8")).toBe(securityInventory(architecture)); expect(fs.statSync(prepared.inventory).mode & 0o777).toBe(0o444); expect( @@ -165,7 +168,7 @@ describe("sandbox base security packages", () => { .filter((line) => line.startsWith("download ")) .map((line) => line.slice(line.lastIndexOf("/") + 1)), ).toEqual([ - `libexpat1_2.8.2-1_${architecture}.deb`, + `libexpat1_2.8.3-1_${architecture}.deb`, `libonig5_6.9.9-1+b1_${architecture}.deb`, `libjq1_1.8.2-1_${architecture}.deb`, `jq_1.8.2-1_${architecture}.deb`,