build(plugin): Add dependency locking and verification to plugin-build (GRADLE-104)#1256
Conversation
| io.grpc:grpc-stub:1.69.1=testRuntimeClasspath | ||
| io.grpc:grpc-util:1.69.1=testRuntimeClasspath | ||
| io.netty:netty-buffer:4.1.110.Final=testRuntimeClasspath | ||
| io.netty:netty-codec-http2:4.1.110.Final=testRuntimeClasspath |
There was a problem hiding this comment.
High severity vulnerability introduced by a package you're using:
Line 100 lists a dependency (io.netty:netty-codec-http2) with a known High severity vulnerability. Fixing requires upgrading or replacing the dependency.
ℹ️ Why this matters
Affected versions of io.grpc:grpc-netty-shaded and io.netty:netty-codec-http2 are vulnerable to Allocation of Resources Without Limits or Throttling. Netty's HTTP/2 implementation fails to correctly track active streams when sending RST_STREAM in response to certain malformed control frames. An attacker can send, for example, WINDOW_UPDATE frames with a zero or overflow increment, HEADERS/DATA on a half-closed stream, or PRIORITY frames with invalid length to trigger RST_STREAMs; each reset decrements Netty's concurrent-stream counter even though the request is still processed. By repeating this on a single connection, the attacker can open an unbounded number of streams, exhausting CPU and memory and causing a denial of service. This is a protocol level attack.
To resolve this comment:
Upgrade this dependency to at least version 4.1.124.Final at plugin-build/gradle.lockfile.
💬 Ignore this finding
To ignore this, reply with:
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
You can view more details on this finding in the Semgrep AppSec Platform here.
12fc51b to
86ac005
Compare
86ac005 to
91533ad
Compare
plugin-build (GRADLE-104)
0xadam-brown
left a comment
There was a problem hiding this comment.
Nice! Coordinate + content locks look great.
m: Two high-level suggestions:
[1] Could be nice to include a pre-merge workflow that warns folks if their lock file needs updating, ie, regenerate the lock file, diff against what's in the PR, and fail if changed.
[2] Have dependabot PRs self-heal w/r/t the lock file.
Eg, i) extract lock file generation into a script, ii) trigger a small workflow on pull_request from dependabot/* when gradle/, plugin-build/, or buildSrc/** change, and iii) re-run the script from (i). (Or whatever makes sense...)
[1] is optional, but I think we should do [2], lest our dependabot life become even busier. Either here or in a fast-follow is fine by me. Thoughts?
|
Yeah those are good points. |
3c44476 to
92718d0
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 92718d0. Configure here.
92718d0 to
630801b
Compare
0xadam-brown
left a comment
There was a problem hiding this comment.
Thanks for the updates 💯
A few non-blockers if you want them.
romtsn
left a comment
There was a problem hiding this comment.
LGTM, good stuff! If you want to take the renovate path, I'd already run it through legal a while ago, and it should be enabled for this repo. I don't think there's a requirement to use dependabot strictly.
Pin the transitive dependencies of the published plugin build to harden against supply-chain risk. Gradle dependency locking records resolved versions in a lockfile and fails the build (STRICT mode) on unexpected drift, while dependency verification checks a SHA-256 checksum for every resolved artifact. Scoped to plugin-build only, the build that produces the shipped artifact. The metadata captures the formatter (spotless), docs (dokka), and publish tooling in addition to the project configurations, so the existing CI enforces both controls without new workflow steps. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…DLE-104) The compatibility test matrix overrides AGP/Kotlin/Gradle versions, which deliberately diverges from the lockfile and verification metadata of the canonical build. Guard dependency locking so it only applies when no VERSION_AGP/VERSION_KOTLIN override is set, and disable dependency verification on the matrix and standalone integration-test steps. Canonical builds (pre-merge, publish, distribution) keep strict locking and verification. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adding, removing, or bumping a dependency in plugin-build invalidates the lockfile and verification metadata, and STRICT-mode locking fails the build until both are regenerated. Document the single command that rewrites them and point the dependencyLocking block at the new section. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
630801b to
ed784fc
Compare
An agent that bumps a dependency in plugin-build hits a STRICT-mode lock failure with no hint that a regenerate command exists. Add a pointer under Common commands and link to the CONTRIBUTING.md section for detail. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
… (GRADLE-104) A release cut had swept the entry into the released 6.10.0 block under Internal Changes. Move it to a new Unreleased section so the changelog gate finds it, and file it under Security since dependency pinning is supply-chain hardening rather than an internal cleanup. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
| cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} | ||
|
|
||
| - name: Build the Release variants and integrationTest | ||
| run: gradle assembleRelease bundleRelease integrationTest | ||
| # Verification is disabled here because the matrix deliberately overrides | ||
| # AGP/Kotlin/Gradle versions, resolving artifacts not in the metadata. | ||
| run: gradle assembleRelease bundleRelease integrationTest --dependency-verification=off | ||
|
|
||
| - name: Check sentry-debug-meta.properties inside APKs | ||
| run: | |
There was a problem hiding this comment.
Bug: The publish-snapshot.yml workflow is missing the --dependency-verification=off flag required when running from the plugin-build directory, which will cause the snapshot publish to fail.
Severity: CRITICAL
Suggested Fix
Add the --dependency-verification=off flag to the ../gradlew publishAllPublicationsToMavenCentralSnapshotsRepository command within the publish-snapshot.yml workflow. This will align it with the other workflows that run from the plugin-build directory and prevent dependency verification failures for buildscript artifacts.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: .github/workflows/test-matrix-agp-gradle.yaml#L71-L79
Potential issue: The pull request introduces Gradle dependency verification but fails to
apply the necessary `--dependency-verification=off` flag to all relevant workflows.
Specifically, the `publish-snapshot.yml` workflow executes Gradle from the
`plugin-build` directory, which resolves buildscript-classpath artifacts not captured in
the verification metadata. While other workflows like `integration-tests-sentry-cli.yml`
and `test-matrix-agp-gradle.yaml` were correctly updated to disable verification for
this reason, the snapshot publishing workflow was overlooked. This omission will cause
the snapshot publishing job to fail due to verification errors, breaking the ability to
publish new snapshots.
Also affects:
.github/workflows/integration-tests-sentry-cli.yml:35~40

Summary
Hardens the published plugin build against supply-chain risk by pinning its transitive dependencies, scoped to
plugin-build/(the build that produces the shipped artifact). Part of GRADLE-104 / SDK-1316.Two complementary controls, both enforced automatically by existing CI (no workflow changes):
dependencyLocking { lockAllConfigurations() }plus agradle.lockfile. STRICT mode (the default) fails the build on unexpected version drift.gradle/verification-metadata.xmlwith a SHA-256 checksum for every resolved artifact (verify-metadata=true,verify-signatures=false— no PGP keyring to maintain).The verification metadata captures the formatter (spotless), docs (dokka), and publish tooling in addition to the project configurations.
Why the version-matrix tests are exempt
Pinning protects the canonical build (the default versions that ship). But
test-matrix-agp-gradle.yamldeliberately tests compatibility against a matrix of AGP / Kotlin / Gradle versions, set via theVERSION_AGP/VERSION_KOTLINenv vars (read inbuildSrc/.../Dependencies.kt) and thegradle-versionoverride. Those overrides intentionally diverge from the lockfile and the recorded checksums, so pinning and the matrix are fundamentally in conflict:VERSION_KOTLINoverridden,compileClasspathresolves e.g.kotlin-stdlib:2.3.21, but the lockfile pins{strictly 2.0.0}→Dependency version enforced by Dependency Lockingfailure.-p plugin-buildintegration test) resolve artifacts that aren't inverification-metadata.xml(different SDK/AGP versions; the buildscript-classpath.modulefiles) →Dependency verification failed.So we keep pinning on the canonical build and exempt the version-varying jobs:
VERSION_AGP/VERSION_KOTLINoverride is present:--dependency-verification=off.Canonical jobs (
pre-merge,publish, the distribution build) keep strict locking and verification, so the protection that matters for the shipped artifact is fully enforced.Notes for reviewers
./gradlew -p plugin-build resolveAndLockAll --write-locks --write-verification-metadata sha256.This is now documented in CONTRIBUTING.md, and AGENTS.md links to it.
--no-daemon, becauseSystem.getenv()returns the daemon's startup environment (which is why CI, with a fresh daemon per job, behaves correctly).🤖 Generated with Claude Code