From 5353a5cb448a3ca887276788ad79b35d7f4454d6 Mon Sep 17 00:00:00 2001 From: pandeymangg Date: Tue, 22 Sep 2026 15:07:58 +0530 Subject: [PATCH] fix(security): raise vulnerable transitive deps on AGP's plugin classpath The Android Gradle Plugin puts its own tooling on the root build script's classpath: gRPC and Netty (io.grpc:grpc-netty), Bouncy Castle and commons-compress (com.android.tools:sdk-common, :repository), jose4j (bundletool) and JDOM (jetifier). The existing resolutionStrategy in android/build.gradle.kts cannot reach that classpath - it configures the :android project's own configurations, which are resolved separately. So Netty was still resolving at 4.1.93.Final there while the floor read 4.1.138.Final, and Bouncy Castle, jose4j and JDOM had no floor at all. Pin them the same way the Jackson BOM is already pinned for Dokka: a platform and constraints in a buildscript block, which apply before the plugins block resolves. Both only ever raise a version, so a newer one shipped by a future AGP still wins. This clears 51 of the 52 open Dependabot alerts. The last one is kotlin-gradle-plugin, which is already covered by the in-flight Kotlin bumps. Nothing reaches the published AAR: releaseRuntimeClasspath carries none of these, and the generated POM is unchanged. --- build.gradle.kts | 27 ++++++++++++++++++++++++++- gradle/libs.versions.toml | 19 +++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ecf7a23..df1330b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,31 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. + +// The Android Gradle Plugin drags its own tooling onto this build script's classpath: gRPC and +// Netty (io.grpc:grpc-netty), Bouncy Castle (com.android.tools:sdk-common), commons-compress +// (:repository), jose4j (bundletool) and JDOM (jetifier). The resolutionStrategy in +// android/build.gradle.kts cannot reach any of it - that block configures the :android project's +// own configurations, which are resolved separately, so Netty was still landing at 4.1.93.Final +// there while the floor read 4.1.138.Final. +// +// Platforms and constraints only ever raise a version, so a newer one shipped by a future AGP +// still wins. AGP 9 drops gRPC outright, which retires the Netty half of this entirely. +buildscript { + dependencies { + classpath(platform("io.netty:netty-bom:${libs.versions.netty.get()}")) + classpath(platform("com.google.protobuf:protobuf-bom:${libs.versions.protobuf.get()}")) + constraints { + add("classpath", "org.bouncycastle:bcprov-jdk18on:${libs.versions.bouncycastle.get()}") + add("classpath", "org.bouncycastle:bcpkix-jdk18on:${libs.versions.bouncycastle.get()}") + add("classpath", "org.bouncycastle:bcutil-jdk18on:${libs.versions.bouncycastle.get()}") + add("classpath", "org.bitbucket.b_c:jose4j:${libs.versions.jose4j.get()}") + add("classpath", "org.jdom:jdom2:${libs.versions.jdom2.get()}") + add("classpath", "org.apache.commons:commons-compress:${libs.versions.commonsCompress.get()}") + } + } +} + plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.android.library) apply false -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e9c922a..44c0668 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,10 +24,17 @@ databindingCommon = "8.9.2" dokka = "2.2.0" -# Security floors for vulnerable transitive dependencies of the build toolchain: the Android -# Gradle Plugin's Unified Test Platform (netty, protobuf) and Dokka's engine (jackson, jsoup). -# These never reach the published AAR - see the resolutionStrategy blocks in -# android/build.gradle.kts. +# Security floors for vulnerable transitive dependencies of the build toolchain. None of these +# reaches the published AAR - releaseRuntimeClasspath carries none of them. +# +# They are applied in two places, because the toolchain pulls them onto two classpaths that are +# resolved independently: +# +# - build.gradle.kts (root buildscript) - AGP's own plugin classpath. gRPC/Netty, Bouncy +# Castle, commons-compress, jose4j and JDOM live here. This is the classpath Dependabot +# reports against, attributed to settings.gradle.kts. +# - android/build.gradle.kts (resolutionStrategy) - the :android project's configurations, +# including AGP's Unified Test Platform, plus Dokka's engine (jackson, jsoup). # # Dependabot does not track these: its Gradle parser only reaches [versions] through a # `version.ref` in [libraries]/[plugins], and nothing references them. Re-check them by @@ -37,6 +44,10 @@ netty = "4.1.138.Final" protobuf = "3.25.9" jackson = "2.22.2" jsoup = "1.23.2" +bouncycastle = "1.85" +jose4j = "0.9.6" +jdom2 = "2.0.6.1" +commonsCompress = "1.27.1" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }