diff --git a/CHANGELOG.md b/CHANGELOG.md index c22a108..a671653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Fixed + +- **The images no longer trust certificates from the compromised eMudhra + intermediate CAs** (keys disclosed 2026-10-20). Both images now require + `ca-certificates` `20250419+deb13u1`, Node 22.23.4, pip 26.2.2 and `certifi` + 2026.10.19 or newer, and source installs (`pip install -e .`) require the same + `certifi`. curl, git, Python `requests`, pip, Node, and the bundled Trivy and + TruffleHog now reject those chains. Container scanners may still report + CVE-2026-111943 against the Trivy and TruffleHog binaries until they are + rebuilt on Go 1.26.10 or 1.27.3. + ## [3.4.0] - 2026-09-18 Findings for the hardcoded-credential rules now report where a credential is diff --git a/Dockerfile b/Dockerfile index 967c5f9..19d2eb6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,12 +56,22 @@ COPY --from=trufflehog /usr/bin/trufflehog /usr/local/bin/trufflehog COPY --from=opengrep-installer /root/.opengrep /root/.opengrep # System deps + Node.js 22.x + Socket CLI +# ca-certificates must be 20250419+deb13u1 or newer, which drops the roots the +# compromised eMudhra intermediates chain to. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && apt-get install -y --no-install-recommends \ - curl git wget ca-certificates + curl git wget ca-certificates \ + && dpkg --compare-versions "$(dpkg-query -W -f='${Version}' ca-certificates)" ge 20250419+deb13u1 +# pip checks certificates against its own vendored CA bundle, not the system +# store, and the base image's pip trusts the compromised intermediates. 26.2.2 +# vendors certifi 2026.10.19. Upgrade it against the system store fixed above. +RUN python -m pip install --no-cache-dir --cert /etc/ssl/certs/ca-certificates.crt --upgrade "pip>=26.2.2" \ + && python -c 'import sys, pip; sys.exit(tuple(map(int, pip.__version__.split(".")[:3])) < (26, 2, 2))' +# Node rejects the compromised eMudhra intermediates from 22.23.4. RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ - && apt-get install -y nodejs + && apt-get install -y nodejs \ + && node -e 'const [a,b,c]=process.versions.node.split(".").map(Number); process.exit(a>22||(a===22&&(b>23||(b===23&&c>=4)))?0:1)' ARG SOCKET_NPM_CLI_VERSION RUN --mount=type=cache,target=/root/.npm \ npm install -g "socket@${SOCKET_NPM_CLI_VERSION}" diff --git a/Dockerfile.heavy b/Dockerfile.heavy index 26af639..64a839c 100644 --- a/Dockerfile.heavy +++ b/Dockerfile.heavy @@ -30,12 +30,22 @@ COPY --from=trivy /usr/local/bin/trivy /usr/local/bin/trivy COPY --from=trufflehog /usr/bin/trufflehog /usr/local/bin/trufflehog COPY --from=opengrep-installer /root/.opengrep /root/.opengrep +# ca-certificates must be 20250419+deb13u1 or newer, which drops the roots the +# compromised eMudhra intermediates chain to. RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && apt-get install -y --no-install-recommends \ - curl git wget ca-certificates + curl git wget ca-certificates \ + && dpkg --compare-versions "$(dpkg-query -W -f='${Version}' ca-certificates)" ge 20250419+deb13u1 +# pip checks certificates against its own vendored CA bundle, not the system +# store, and the base image's pip trusts the compromised intermediates. 26.2.2 +# vendors certifi 2026.10.19. Upgrade it against the system store fixed above. +RUN python -m pip install --no-cache-dir --cert /etc/ssl/certs/ca-certificates.crt --upgrade "pip>=26.2.2" \ + && python -c 'import sys, pip; sys.exit(tuple(map(int, pip.__version__.split(".")[:3])) < (26, 2, 2))' +# Node rejects the compromised eMudhra intermediates from 22.23.4. RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ - && apt-get install -y nodejs + && apt-get install -y nodejs \ + && node -e 'const [a,b,c]=process.versions.node.split(".").map(Number); process.exit(a>22||(a===22&&(b>23||(b===23&&c>=4)))?0:1)' ARG SOCKET_NPM_CLI_VERSION RUN --mount=type=cache,target=/root/.npm \ npm install -g "socket@${SOCKET_NPM_CLI_VERSION}" @@ -45,10 +55,12 @@ COPY pyproject.toml README.md LICENSE uv.lock /socket-basics/ ENV UV_LINK_MODE=copy ARG SOCKET_PYTHON_CLI_VERSION +# The Python CLI runs on the system interpreter, not the locked venv, so floor +# certifi there too (2026.10.19 drops the compromised eMudhra roots). RUN --mount=type=cache,target=/root/.cache/uv \ pip install -e . \ && uv sync --frozen --no-dev \ - && pip install --no-cache-dir "socketsecurity==${SOCKET_PYTHON_CLI_VERSION}" + && pip install --no-cache-dir "socketsecurity==${SOCKET_PYTHON_CLI_VERSION}" "certifi>=2026.10.19" COPY scripts/docker-heavy-entrypoint.sh /usr/local/bin/docker-heavy-entrypoint.sh RUN chmod +x /usr/local/bin/docker-heavy-entrypoint.sh diff --git a/pyproject.toml b/pyproject.toml index 9a6f9b7..45e63a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,10 @@ dependencies = [ "PyYAML>=6.0.0", "tomli; python_version < '3.11'", "socketdev>=3.5.0", - "jsonschema>=4.25.1" + "jsonschema>=4.25.1", + # requests' CA bundle; 2026.10.19 drops the roots behind the compromised + # eMudhra intermediates. Covers source installs (`pip install -e .`). + "certifi>=2026.10.19" ] [project.optional-dependencies] diff --git a/uv.lock b/uv.lock index a56300b..a9b5905 100644 --- a/uv.lock +++ b/uv.lock @@ -695,6 +695,7 @@ name = "socket-basics" version = "3.4.0" source = { editable = "." } dependencies = [ + { name = "certifi" }, { name = "jsonschema" }, { name = "light-s3-client" }, { name = "pyyaml" }, @@ -715,6 +716,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "black", marker = "extra == 'dev'", specifier = ">=26.5.1" }, + { name = "certifi", specifier = ">=2026.10.19" }, { name = "flake8", marker = "extra == 'dev'", specifier = ">=5.0.0" }, { name = "jsonschema", specifier = ">=4.25.1" }, { name = "light-s3-client", specifier = "~=0.0.30" },