From e25312578b89a392ff0d97faf46dee96553836e0 Mon Sep 17 00:00:00 2001 From: Eliott B <47679741+eliottness@users.noreply.github.com> Date: Mon, 26 Oct 2026 13:40:59 +0100 Subject: [PATCH 1/3] Stop trusting compromised eMudhra roots in the exploration-tests image Upgrade ca-certificates in the debian:bookworm-slim base and delete emSign ECC Root CA - G3 / AAA Certificate Services from every SDKMAN and Gradle-provisioned JDK cacerts in the exploration-tests image (IR-62343). The image is published by the manual build-exploration-tests-image job; re-run it after merge. Jira: APPSEC-71277 --- .../Dockerfile.exploration-tests | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests index 6198af890a7..0704bdc802a 100644 --- a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests +++ b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests @@ -1,5 +1,11 @@ FROM debian:bookworm-slim +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates && \ + apt-get install -y --only-upgrade ca-certificates && \ + update-ca-certificates -f && \ + rm -rf /var/lib/apt/lists/* + RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y procps tini build-essential git curl unzip zip && \ apt-get -y clean && \ @@ -50,3 +56,21 @@ RUN git clone -b okhttp_5.3.x https://github.com/square/okhttp.git COPY okhttp_exploration-tests.patch . RUN cd okhttp && git apply /exploration-tests/okhttp_exploration-tests.patch RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk use java 17.0.10-tem && cd okhttp && ./gradlew dependencies" + +# Remove compromised CA entries from every SDKMAN and Gradle-provisioned JDK. +RUN set -eu; \ + mkdir -p "$HOME/.gradle/jdks"; \ + keytool="$HOME/.sdkman/candidates/java/17.0.10-tem/bin/keytool"; \ + find "$HOME/.sdkman/candidates/java" "$HOME/.gradle/jdks" -type f -path '*/lib/security/cacerts' | \ + while IFS= read -r store; do \ + "$keytool" -list -v -keystore "$store" -storepass changeit | \ + awk '/^Alias name: / { alias = substr($0, 13) } /^Owner: .*([eE]mSign ECC Root CA - G3|AAA Certificate Services)/ { print alias }' | \ + while IFS= read -r alias; do \ + "$keytool" -delete -keystore "$store" -storepass changeit -alias "$alias"; \ + done; \ + done + +# Do not publish Gradle's generated API jar with its old embedded CA snapshot. +RUN if [ -d "$HOME/.gradle/caches" ]; then \ + find "$HOME/.gradle/caches" -type f -path '*/generated-gradle-jars/gradle-api-*.jar' -delete; \ + fi From 28cc04f456b7b195777af672a322d5ed465f4358 Mon Sep 17 00:00:00 2001 From: Eliott B <47679741+eliottness@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:07:12 +0100 Subject: [PATCH 2/3] Scrub exploration-test JDKs before dependency downloads Preinstall Java 11 and explicitly constrain Gradle toolchain paths so the OkHttp job cannot create an unscrubbed JDK at runtime. Scrub all four affected roots before resolving Maven and Gradle dependencies, and remove them from cached Google PKCS12 and JKS truststores after warm-up. Co-authored-by: sisyphus-dev-ai --- .../Dockerfile.exploration-tests | 58 +++++++++++++++---- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests index 0704bdc802a..fef5361383a 100644 --- a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests +++ b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests @@ -18,9 +18,32 @@ RUN curl -fsSL --retry 5 --retry-delay 2 --retry-connrefused -o /tmp/sdkman-inst rm /tmp/sdkman-install.sh RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && \ sdk env install && \ - sdk install java 17.0.10-tem && \ + sdk install java 11.0.32.1+1-tem && \ + sdk install java 17.0.21.0+9-tem && \ sdk flush" +ENV JAVA_11_HOME=/root/.sdkman/candidates/java/11.0.32.1+1-tem +# Keep OkHttp's Java 11 test launcher on the scrubbed image JDK, not a runtime download. +RUN mkdir -p "$HOME/.gradle" && \ + printf '%s\n' \ + "org.gradle.java.installations.paths=$JAVA_11_HOME,$HOME/.sdkman/candidates/java/8.0.372-tem,$HOME/.sdkman/candidates/java/17.0.21.0+9-tem" \ + 'org.gradle.java.installations.auto-download=false' > "$HOME/.gradle/gradle.properties" + +# Distrust the affected roots before Maven or Gradle downloads any build inputs. +RUN set -eu; \ + keytool="$HOME/.sdkman/candidates/java/17.0.21.0+9-tem/bin/keytool"; \ + find "$HOME/.sdkman/candidates/java" -type f -path '*/lib/security/cacerts' | \ + while IFS= read -r store; do \ + listing=$("$keytool" -list -v -keystore "$store" -storepass changeit); \ + aliases=$(printf '%s\n' "$listing" | \ + awk '/^Alias name: / { alias = substr($0, 13) } /^Owner: .*([eE]mSign (ECC )?Root CA - G[123]|AAA Certificate Services)/ { print alias }'); \ + if [ -n "$aliases" ]; then \ + printf '%s\n' "$aliases" | while IFS= read -r alias; do \ + "$keytool" -delete -keystore "$store" -storepass changeit -alias "$alias"; \ + done; \ + fi; \ + done + RUN mkdir exploration-tests WORKDIR /exploration-tests # jsoup @@ -55,19 +78,30 @@ RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && cd jackson-databind && m RUN git clone -b okhttp_5.3.x https://github.com/square/okhttp.git COPY okhttp_exploration-tests.patch . RUN cd okhttp && git apply /exploration-tests/okhttp_exploration-tests.patch -RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk use java 17.0.10-tem && cd okhttp && ./gradlew dependencies" +RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk use java 17.0.21.0+9-tem && cd okhttp && ./gradlew dependencies" -# Remove compromised CA entries from every SDKMAN and Gradle-provisioned JDK. +# Older google-api-client artifacts embed independent Google truststores. RUN set -eu; \ - mkdir -p "$HOME/.gradle/jdks"; \ - keytool="$HOME/.sdkman/candidates/java/17.0.10-tem/bin/keytool"; \ - find "$HOME/.sdkman/candidates/java" "$HOME/.gradle/jdks" -type f -path '*/lib/security/cacerts' | \ - while IFS= read -r store; do \ - "$keytool" -list -v -keystore "$store" -storepass changeit | \ - awk '/^Alias name: / { alias = substr($0, 13) } /^Owner: .*([eE]mSign ECC Root CA - G3|AAA Certificate Services)/ { print alias }' | \ - while IFS= read -r alias; do \ - "$keytool" -delete -keystore "$store" -storepass changeit -alias "$alias"; \ - done; \ + keytool="$HOME/.sdkman/candidates/java/17.0.21.0+9-tem/bin/keytool"; \ + find "$HOME/.gradle" -type f -name 'google-api-client-*.jar' | \ + while IFS= read -r archive; do \ + for entry in com/google/api/client/googleapis/google.p12 com/google/api/client/googleapis/google.jks; do \ + if unzip -Z1 "$archive" | grep -Fxq "$entry"; then \ + scratch="$(mktemp -d)"; \ + mkdir -p "$scratch/com/google/api/client/googleapis"; \ + unzip -p "$archive" "$entry" > "$scratch/$entry"; \ + listing=$("$keytool" -list -v -keystore "$scratch/$entry" -storepass notasecret); \ + aliases=$(printf '%s\n' "$listing" | \ + awk '/^Alias name: / { alias = substr($0, 13) } /^Owner: .*([eE]mSign (ECC )?Root CA - G[123]|AAA Certificate Services)/ { print alias }'); \ + if [ -n "$aliases" ]; then \ + printf '%s\n' "$aliases" | while IFS= read -r alias; do \ + "$keytool" -delete -keystore "$scratch/$entry" -storepass notasecret -alias "$alias"; \ + done; \ + (cd "$scratch" && zip -q "$archive" "$entry"); \ + fi; \ + rm -rf "$scratch"; \ + fi; \ + done; \ done # Do not publish Gradle's generated API jar with its old embedded CA snapshot. From 75ecc773591eeaafde2c1ee7cdf7429f1b338a76 Mon Sep 17 00:00:00 2001 From: Eliott B <47679741+eliottness@users.noreply.github.com> Date: Wed, 28 Oct 2026 11:31:04 +0100 Subject: [PATCH 3/3] Make the exploration-test JDK versions build args Addresses review: the Java 11 and 17 SDKMAN versions are declared once as ARGs and reused. --- .../Dockerfile.exploration-tests | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests index fef5361383a..be436b18217 100644 --- a/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests +++ b/dd-java-agent/agent-debugger/exploration-tests/Dockerfile.exploration-tests @@ -1,5 +1,8 @@ FROM debian:bookworm-slim +ARG JAVA_11_VERSION=11.0.32.1+1-tem +ARG JAVA_17_VERSION=17.0.21.0+9-tem + RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates && \ apt-get install -y --only-upgrade ca-certificates && \ @@ -18,20 +21,20 @@ RUN curl -fsSL --retry 5 --retry-delay 2 --retry-connrefused -o /tmp/sdkman-inst rm /tmp/sdkman-install.sh RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && \ sdk env install && \ - sdk install java 11.0.32.1+1-tem && \ - sdk install java 17.0.21.0+9-tem && \ + sdk install java ${JAVA_11_VERSION} && \ + sdk install java ${JAVA_17_VERSION} && \ sdk flush" -ENV JAVA_11_HOME=/root/.sdkman/candidates/java/11.0.32.1+1-tem +ENV JAVA_11_HOME=/root/.sdkman/candidates/java/${JAVA_11_VERSION} # Keep OkHttp's Java 11 test launcher on the scrubbed image JDK, not a runtime download. RUN mkdir -p "$HOME/.gradle" && \ printf '%s\n' \ - "org.gradle.java.installations.paths=$JAVA_11_HOME,$HOME/.sdkman/candidates/java/8.0.372-tem,$HOME/.sdkman/candidates/java/17.0.21.0+9-tem" \ + "org.gradle.java.installations.paths=$JAVA_11_HOME,$HOME/.sdkman/candidates/java/8.0.372-tem,$HOME/.sdkman/candidates/java/${JAVA_17_VERSION}" \ 'org.gradle.java.installations.auto-download=false' > "$HOME/.gradle/gradle.properties" # Distrust the affected roots before Maven or Gradle downloads any build inputs. RUN set -eu; \ - keytool="$HOME/.sdkman/candidates/java/17.0.21.0+9-tem/bin/keytool"; \ + keytool="$HOME/.sdkman/candidates/java/${JAVA_17_VERSION}/bin/keytool"; \ find "$HOME/.sdkman/candidates/java" -type f -path '*/lib/security/cacerts' | \ while IFS= read -r store; do \ listing=$("$keytool" -list -v -keystore "$store" -storepass changeit); \ @@ -78,11 +81,11 @@ RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && cd jackson-databind && m RUN git clone -b okhttp_5.3.x https://github.com/square/okhttp.git COPY okhttp_exploration-tests.patch . RUN cd okhttp && git apply /exploration-tests/okhttp_exploration-tests.patch -RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk use java 17.0.21.0+9-tem && cd okhttp && ./gradlew dependencies" +RUN bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk use java ${JAVA_17_VERSION} && cd okhttp && ./gradlew dependencies" # Older google-api-client artifacts embed independent Google truststores. RUN set -eu; \ - keytool="$HOME/.sdkman/candidates/java/17.0.21.0+9-tem/bin/keytool"; \ + keytool="$HOME/.sdkman/candidates/java/${JAVA_17_VERSION}/bin/keytool"; \ find "$HOME/.gradle" -type f -name 'google-api-client-*.jar' | \ while IFS= read -r archive; do \ for entry in com/google/api/client/googleapis/google.p12 com/google/api/client/googleapis/google.jks; do \