You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.
Summary
Vendored Maven refuses aggregator roots (vendor_maven_multimodule_unsupported). Hosted Maven does neither of the following:
refuse the aggregator, or
read the child poms.
When a module declares the patched GA with a literal base version, the rewriter can't find it in the root. It falls into the "transitive" branch and adds a root <dependencyManagement> pin. A child's literal <version> always beats an inherited depMgmt entry, so that module keeps resolving the unpatched upstream jar.
The scan reports redirected: 1, and socket-patch vex attests not_affected. VEX reads only the root pom, sees the suffixed depMgmt pin plus the repository, and trusts it.
Impact
The module stays silently unpatched, which is fail-open.
The VEX statement for the product is false.
Multi-module builds are the norm for non-trivial Maven projects.
child/pom.xml: <parent>com.example:root:1.0.0</parent>, with a dependency on org.apache.commons:commons-lang3<version>3.12.0</version>.
Grant: commons-lang3 3.12.0 → 3.12.0-socket.4d5e6f70, from the basic golden override.
socket-patch scan --mode hosted --json --yes ...
-> exit 0, redirected=1, rewrittenFiles=[.mvn/checksums/checksums.sha256, .mvn/maven.config, pom.xml]
warnings=[redirect_maven_dep_management_added]; child/pom.xml untouched
socket-patch vex --no-verify --product pkg:maven/com.example/[email protected]
-> exit 0, not_affected for pkg:maven/org.apache.commons/[email protected]
mvn 3.9.6 -B dependency:3.6.1:copy-dependencies (fresh local repo; Socket repo mirrored to a stub)
-> Downloaded from central-https: .../commons-lang3/3.12.0/commons-lang3-3.12.0.jar
BUILD SUCCESS; child/target/dependency/commons-lang3-3.12.0.jar is PRISTINE
Control: the child omits <version> and the root manages 3.12.0 in <dependencyManagement>. Here the root literal is rewritten, and the child resolves commons-lang3-3.12.0-socket.4d5e6f70.jar (PATCHED) from the Socket repo. So the gap is specific to module-level literals, and to modules that do not inherit from the root.
Expected vs actual
Expected, one of:
(a) Refuse aggregator roots in hosted mode, like vendored mode does (<modules>, and Maven 4 <subprojects>).
(b) Walk the reactor (the <modules>/<subprojects> paths) and rewrite each module pom that declares the GA. This is what cargo hosted does for workspace members since Fix Cargo hosted workspace redirects #256.
At minimum: do not count a depMgmt-only pin as redirected when any module declares its own literal, and have VEX discovery refuse to attest a root pin that a module overrides.
Actual: silent fail-open with a positive VEX.
CLI revision
3efdc31d
Suggested fix
Option (b) mirrors the cargo workspace-member handling. Option (a) is a one-line parity fix using declares_modules (plus subprojects). Either way, VEX discovery (vex/discover/maven.rs) should also look at module poms, or refuse when the root is an aggregator.
[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.
Summary
Vendored Maven refuses aggregator roots (
vendor_maven_multimodule_unsupported). Hosted Maven does neither of the following:When a module declares the patched GA with a literal base version, the rewriter can't find it in the root. It falls into the "transitive" branch and adds a root
<dependencyManagement>pin. A child's literal<version>always beats an inherited depMgmt entry, so that module keeps resolving the unpatched upstream jar.The scan reports
redirected: 1, andsocket-patch vexattestsnot_affected. VEX reads only the root pom, sees the suffixed depMgmt pin plus the repository, and trusts it.Impact
Multi-module builds are the norm for non-trivial Maven projects.
Repro
Root
pom.xml:child/pom.xml:<parent>com.example:root:1.0.0</parent>, with a dependency onorg.apache.commons:commons-lang3<version>3.12.0</version>.Grant: commons-lang3 3.12.0 →
3.12.0-socket.4d5e6f70, from thebasicgolden override.Control: the child omits
<version>and the root manages3.12.0in<dependencyManagement>. Here the root literal is rewritten, and the child resolvescommons-lang3-3.12.0-socket.4d5e6f70.jar(PATCHED) from the Socket repo. So the gap is specific to module-level literals, and to modules that do not inherit from the root.Expected vs actual
<modules>, and Maven 4<subprojects>).<modules>/<subprojects>paths) and rewrite each module pom that declares the GA. This is what cargo hosted does for workspace members since Fix Cargo hosted workspace redirects #256.CLI revision
3efdc31dSuggested fix
Option (b) mirrors the cargo workspace-member handling. Option (a) is a one-line parity fix using
declares_modules(plussubprojects). Either way, VEX discovery (vex/discover/maven.rs) should also look at module poms, or refuse when the root is an aggregator.File refs (at 3efdc31)
crates/socket-patch-cli/src/commands/scan/hosted.rs:70-81(only rootpom.xml/.mvn/*are read)crates/socket-patch-core/src/patch/redirect/mod.rs:6143-6170(a GA absent from the root becomes a depMgmt pin)crates/socket-patch-core/src/vendor/maven_repo.rs:242,1109(the vendored-side refusal hosted lacks)