From 1d2803294ddd0a85b8b2b355ccd83101663bdb9a Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Fri, 23 Oct 2026 16:52:22 -0700 Subject: [PATCH] Patch pip to use the system CA bundle on 3.11 and 3.12 Upstream is not updating the pip bundled with 3.11 and 3.12, and its vendored "certifi" bundle still trusts a compromised CA. Apply Debian's "certifi-debian-ca-certificates" patch (downloaded via a raw URL pinned to a Debian commit and verified by checksum, with the Debian branding adjusted on Alpine) to both the installed pip and the bundled "ensurepip" wheel so new venvs are covered too. Keyed on the exact versions so any upstream update drops it automatically. --- 3.11/alpine3.23/Dockerfile | 20 ++++++++++++++++++++ 3.11/alpine3.24/Dockerfile | 20 ++++++++++++++++++++ 3.11/bookworm/Dockerfile | 17 +++++++++++++++++ 3.11/slim-bookworm/Dockerfile | 18 ++++++++++++++++++ 3.11/slim-trixie/Dockerfile | 18 ++++++++++++++++++ 3.11/trixie/Dockerfile | 17 +++++++++++++++++ 3.12/alpine3.23/Dockerfile | 20 ++++++++++++++++++++ 3.12/alpine3.24/Dockerfile | 20 ++++++++++++++++++++ 3.12/bookworm/Dockerfile | 17 +++++++++++++++++ 3.12/slim-bookworm/Dockerfile | 18 ++++++++++++++++++ 3.12/slim-trixie/Dockerfile | 18 ++++++++++++++++++ 3.12/trixie/Dockerfile | 17 +++++++++++++++++ Dockerfile-linux.template | 30 ++++++++++++++++++++++++++++++ 13 files changed, 250 insertions(+) diff --git a/3.11/alpine3.23/Dockerfile b/3.11/alpine3.23/Dockerfile index 517c5c645..3ef8c6fb8 100644 --- a/3.11/alpine3.23/Dockerfile +++ b/3.11/alpine3.23/Dockerfile @@ -48,6 +48,7 @@ RUN set -eux; \ make \ ncurses-dev \ openssl-dev \ + patch \ pax-utils \ readline-dev \ sqlite-dev \ @@ -102,6 +103,25 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum -c -; \ +# the patch hard-codes "Debian" branding into the code it injects + sed --in-place --expression 's/DEBIAN/ALPINE/g' --expression 's/Debian/Alpine/g' pip.patch; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.11/alpine3.24/Dockerfile b/3.11/alpine3.24/Dockerfile index 2d9b4c568..0a66540de 100644 --- a/3.11/alpine3.24/Dockerfile +++ b/3.11/alpine3.24/Dockerfile @@ -48,6 +48,7 @@ RUN set -eux; \ make \ ncurses-dev \ openssl-dev \ + patch \ pax-utils \ readline-dev \ sqlite-dev \ @@ -102,6 +103,25 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum -c -; \ +# the patch hard-codes "Debian" branding into the code it injects + sed --in-place --expression 's/DEBIAN/ALPINE/g' --expression 's/Debian/Alpine/g' pip.patch; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.11/bookworm/Dockerfile b/3.11/bookworm/Dockerfile index d5007a081..76762068e 100644 --- a/3.11/bookworm/Dockerfile +++ b/3.11/bookworm/Dockerfile @@ -74,6 +74,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ # enable GDB to load debugging data: https://github.com/docker-library/python/pull/701 bin="$(readlink -ve /usr/local/bin/python3)"; \ dir="$(dirname "$bin")"; \ diff --git a/3.11/slim-bookworm/Dockerfile b/3.11/slim-bookworm/Dockerfile index 7b5f38efc..865d943eb 100644 --- a/3.11/slim-bookworm/Dockerfile +++ b/3.11/slim-bookworm/Dockerfile @@ -53,6 +53,7 @@ RUN set -eux; \ libsqlite3-dev \ libssl-dev \ make \ + patch \ tk-dev \ uuid-dev \ wget \ @@ -101,6 +102,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.11/slim-trixie/Dockerfile b/3.11/slim-trixie/Dockerfile index d480e5e51..74e4ecb1b 100644 --- a/3.11/slim-trixie/Dockerfile +++ b/3.11/slim-trixie/Dockerfile @@ -53,6 +53,7 @@ RUN set -eux; \ libsqlite3-dev \ libssl-dev \ make \ + patch \ tk-dev \ uuid-dev \ wget \ @@ -101,6 +102,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.11/trixie/Dockerfile b/3.11/trixie/Dockerfile index 3d4ae0d23..1f156bc1e 100644 --- a/3.11/trixie/Dockerfile +++ b/3.11/trixie/Dockerfile @@ -74,6 +74,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.11/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.11/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.11/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ # enable GDB to load debugging data: https://github.com/docker-library/python/pull/701 bin="$(readlink -ve /usr/local/bin/python3)"; \ dir="$(dirname "$bin")"; \ diff --git a/3.12/alpine3.23/Dockerfile b/3.12/alpine3.23/Dockerfile index 7e9434031..c871af313 100644 --- a/3.12/alpine3.23/Dockerfile +++ b/3.12/alpine3.23/Dockerfile @@ -48,6 +48,7 @@ RUN set -eux; \ make \ ncurses-dev \ openssl-dev \ + patch \ pax-utils \ readline-dev \ sqlite-dev \ @@ -120,6 +121,25 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum -c -; \ +# the patch hard-codes "Debian" branding into the code it injects + sed --in-place --expression 's/DEBIAN/ALPINE/g' --expression 's/Debian/Alpine/g' pip.patch; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.12/alpine3.24/Dockerfile b/3.12/alpine3.24/Dockerfile index 66b4e977e..8fd591aee 100644 --- a/3.12/alpine3.24/Dockerfile +++ b/3.12/alpine3.24/Dockerfile @@ -48,6 +48,7 @@ RUN set -eux; \ make \ ncurses-dev \ openssl-dev \ + patch \ pax-utils \ readline-dev \ sqlite-dev \ @@ -120,6 +121,25 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum -c -; \ +# the patch hard-codes "Debian" branding into the code it injects + sed --in-place --expression 's/DEBIAN/ALPINE/g' --expression 's/Debian/Alpine/g' pip.patch; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.12/bookworm/Dockerfile b/3.12/bookworm/Dockerfile index 77161177a..518f4fd91 100644 --- a/3.12/bookworm/Dockerfile +++ b/3.12/bookworm/Dockerfile @@ -92,6 +92,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ # enable GDB to load debugging data: https://github.com/docker-library/python/pull/701 bin="$(readlink -ve /usr/local/bin/python3)"; \ dir="$(dirname "$bin")"; \ diff --git a/3.12/slim-bookworm/Dockerfile b/3.12/slim-bookworm/Dockerfile index 474bb4d25..a82b9cd26 100644 --- a/3.12/slim-bookworm/Dockerfile +++ b/3.12/slim-bookworm/Dockerfile @@ -53,6 +53,7 @@ RUN set -eux; \ libsqlite3-dev \ libssl-dev \ make \ + patch \ tk-dev \ uuid-dev \ wget \ @@ -119,6 +120,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.12/slim-trixie/Dockerfile b/3.12/slim-trixie/Dockerfile index 6851c2efc..fc3d56829 100644 --- a/3.12/slim-trixie/Dockerfile +++ b/3.12/slim-trixie/Dockerfile @@ -53,6 +53,7 @@ RUN set -eux; \ libsqlite3-dev \ libssl-dev \ make \ + patch \ tk-dev \ uuid-dev \ wget \ @@ -119,6 +120,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ cd /; \ rm -rf /usr/src/python; \ \ diff --git a/3.12/trixie/Dockerfile b/3.12/trixie/Dockerfile index fef58139b..8c4d87937 100644 --- a/3.12/trixie/Dockerfile +++ b/3.12/trixie/Dockerfile @@ -92,6 +92,23 @@ RUN set -eux; \ ; \ make install; \ \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum --strict --check -; \ + pipWhl="$(echo /usr/local/lib/python3.12/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python3.12/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python3.12/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ + \ # enable GDB to load debugging data: https://github.com/docker-library/python/pull/701 bin="$(readlink -ve /usr/local/bin/python3)"; \ dir="$(dirname "$bin")"; \ diff --git a/Dockerfile-linux.template b/Dockerfile-linux.template index 2509ecddb..ae3dac2cb 100644 --- a/Dockerfile-linux.template +++ b/Dockerfile-linux.template @@ -8,6 +8,11 @@ def rcVersion: env.version | rtrimstr("-rc") ; + def pip_certifi_patch: + # https://github.com/docker-library/python/issues/1142 + # only the exact versions we have verified, so any upstream update (which might include a newer pip or other mitigations) drops this automatically + IN(.version; "3.11.17", "3.12.15") + ; def clean_apt: # TODO once bookworm is EOL, remove this and just hard-code "apt-get dist-clean" instead if env.variant | contains("bookworm") then @@ -107,6 +112,7 @@ RUN set -eux; \ "make", "ncurses-dev", "openssl-dev", + if pip_certifi_patch then "patch" else empty end, "pax-utils", "readline-dev", "sqlite-dev", @@ -145,6 +151,7 @@ RUN set -eux; \ "libsqlite3-dev", "libssl-dev", "make", + if pip_certifi_patch then "patch" else empty end, "tk-dev", "uuid-dev", "wget", @@ -280,6 +287,29 @@ RUN set -eux; \ python \ ; \ make install; \ +{{ if pip_certifi_patch then ( -}} + \ +# https://github.com/docker-library/python/issues/1142 +# pip's vendored "certifi" bundle trusts a compromised CA, and upstream is not updating the pip bundled with this version, so patch pip (and the "ensurepip" wheel, for new venvs) to use the system CA bundle instead (like Debian does) + wget -O pip.patch 'https://salsa.debian.org/python-team/packages/python-pip/-/raw/6f4f079131dcc2902600cee89aa54ef099d32345/debian/patches/certifi-debian-ca-certificates.patch'; \ + echo 'ddb4b85f9468bd9778afed0abd91a7b9af4ec6028c5efbcc236a9f6711cbaa40 *pip.patch' | sha256sum {{ if is_alpine then "-c" else "--strict --check" end }} -; \ +{{ if is_alpine then ( -}} +# the patch hard-codes "Debian" branding into the code it injects + sed --in-place --expression 's/DEBIAN/ALPINE/g' --expression 's/Debian/Alpine/g' pip.patch; \ +{{ ) else "" end -}} + pipWhl="$(echo /usr/local/lib/python{{ rcVersion }}/ensurepip/_bundled/pip-*.whl)"; \ + [ -s "$pipWhl" ]; \ + pipDir="$(mktemp -d)"; \ + python3 -m zipfile --extract "$pipWhl" "$pipDir"; \ + patch --directory "$pipDir" --strip 2 --input "$PWD/pip.patch"; \ + python3 -c 'import shutil, sys; shutil.make_archive(*sys.argv[1:])' "$PWD/pip-patched" zip "$pipDir"; \ + mv -v pip-patched.zip "$pipWhl"; \ + rm -rf "$pipDir"; \ + patch --directory /usr/local/lib/python{{ rcVersion }}/site-packages --strip 2 --input "$PWD/pip.patch"; \ + for pipPath in "$pipWhl" /usr/local/lib/python{{ rcVersion }}/site-packages; do \ + python3 -c 'import sys; sys.path.insert(0, sys.argv[1]); from pip._vendor import certifi; assert certifi.where() == "/etc/ssl/certs/ca-certificates.crt"' "$pipPath"; \ + done; \ +{{ ) else "" end -}} {{ if is_alpine or is_slim then "" else ( -}} \ # enable GDB to load debugging data: https://github.com/docker-library/python/pull/701