Symptom

Kraken’s nightly dependency-CVE scan opened #863: one open Dependabot alert (medium) on org.apache.commons:commons-lang3, range >= 3.0, < 3.18.0, GHSA-j288-q9x7-2f5v. The lead’s hypothesis was to add an explicit commons-lang3 = "3.18.0" entry to gradle/libs.versions.toml.

That entry — plus an allprojects { configurations.configureEach { resolutionStrategy.eachDependency { … } } } floor in build.gradle.kts — already existed, landed in #431, an ancestor of the commit Kraken scanned. The alert was open anyway.

Root cause

Same shape as #850 (Bouncy Castle, see 2026-07-14-bouncycastle-buildscript-force-misses-project-configs.md): a pin’s scope is part of the pin. The allprojects rule reaches every project configuration, and :server:dependencyInsight --configuration jvmRuntimeClasspath --dependency commons-lang3 confirms it’s working — :server resolves commons-lang3:3.18.0 via commons-compressdataframe-arrow/poi-ooxmlkandy, selected by the project-level rule.

But ./gradlew buildEnvironment (the buildscript classpath — Gradle plugins themselves, resolved independently of project configs) showed commons-lang3 3.16.0 -> commons-lang3 with no override: AGP 9.2.1 → com.android.tools:repository :32.2.1commons-compress:1.27.1commons-lang3:3.16.0, still below the 3.18.0 floor. The existing buildscript { configurations.all { resolutionStrategy.force(...) } } block already forces Bouncy Castle, jose4j, jdom2 and plexus-utils for exactly this reason (buildscript classpath ≠ project classpath) but had never been extended to cover commons-lang3, because the original #431 fix only needed to cover :server’s runtime classpath at the time.

Kraken’s “shippable runtime” classification did not hold up — this coordinate lives in AGP’s own tooling (Android Gradle Plugin build-time resolution), never on a packaged runtime classpath, matching the BC precedent’s “build/toolchain only.”

Fix

build.gradle.kts — added "org.apache.commons:commons-lang3:3.18.0" to the existing buildscript resolutionStrategy.force(...) list (literal version string, matching the other five buildscript-block forces — the version catalog isn’t wired into that block). Verified with ./gradlew buildEnvironment before/after: 3.16.03.16.0 -> 3.18.0. No change needed to gradle/libs.versions.toml or the project-level allprojects rule — both already correct since #431.

Prevention