[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 mode wires socket-patch-vendor-<uuid> (file://${project.basedir}/.socket/vendor/maven/<uuid>) and appends it last in <repositories>. The vendored GAV is the original upstream GAV, so it has no suffix. As a result, any repository Maven consults first that also has the GAV wins, and the pristine jar is used.
This happens with:
- An earlier project
<repository>, for example the company's Central proxy declared in the pom. Maven tries declared repositories in order.
- A
settings.xml <mirror><mirrorOf>*</mirrorOf>. * also captures file:// repositories, so the vendored repo is rerouted to the mirror. (external:* does not capture them, and the vendored repo is honored.) docs/ecosystems.md documents mirrorOf * only for hosted mode, where it fails loudly. In vendored mode it fails open.
In both cases, vendor succeeds and socket-patch vex --offline attests not_affected, because the vendored tree, the jar and its .sha1 are all intact.
Impact
The project is silently unpatched with a positive VEX. Both shapes are common in enterprise builds.
This is the same failure class as the documented warm-~/.m2 shadow, but there is no warning for it. The always-on vendor_maven_local_cache_shadow covers only the local repository.
Repro
The patch is commons-lang3 3.12.0 with a patched META-INF/NOTICE.txt, set up with a hand-staged .socket/manifest.json + blob and then vendor --json --offline, as in e2e_vendor_maven_build. After that:
- The manifest and blobs are removed (fresh checkout).
- Maven runs
dependency:3.6.1:copy-dependencies with a fresh local repository.
Pom with a pre-existing repository:
<repositories>
<repository><id>corp-proxy</id><url>https://repo.maven.apache.org/maven2</url></repository>
</repositories>
After vendor, the repository order is corp-proxy, then socket-patch-vendor-4d5e6f70-….
| case |
Maven 3.9.6 |
Maven 4.0.0-rc-7 |
| control (no other repos, plain settings) |
PATCHED (from socket-patch-vendor-…) |
PATCHED |
corp-proxy declared before |
PRISTINE (Downloaded from corp-proxy) |
PRISTINE |
control + settings <mirrorOf>*</mirrorOf> |
PRISTINE (Downloaded from corp-mirror) |
PRISTINE |
control + settings <mirrorOf>external:*</mirrorOf> |
PATCHED |
PATCHED |
vex --offline --product pkg:maven/com.example/[email protected] in the corp-proxy case gives exit 0 and not_affected for pkg:maven/org.apache.commons/[email protected].
Expected vs actual
- Expected:
- Insert the vendored repository first, as hosted mode does, using the same comment/profile-safe anchor.
- Warn when the pom or the user's
settings.xml has a mirrorOf of *, or a pattern matching socket-patch-vendor-*. Document *,!socket-patch-vendor-*.
- VEX discovery should refuse to attest a vendored ref that is not the first repository.
- Actual: appended last, no warning, positive VEX.
CLI revision
3efdc31d
Suggested fix
- In
build_repo_edit, anchor on the first wireable <repositories> open tag and insert right after it.
- Extend the
vendor_maven_local_cache_shadow family with a vendor_maven_repository_shadow warning when other repositories exist.
- Add a docs note for
mirrorOf * under vendored.
File refs (at 3efdc31)
crates/socket-patch-core/src/vendor/maven_repo.rs:968-985 (build_repo_edit anchors on </repositories>, i.e. appends)
crates/socket-patch-core/src/vendor/maven_repo.rs:1089-1103 (repository_block)
docs/ecosystems.md:171-186 (warm-cache note; mirrorOf note is hosted-only)
[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 mode wires
socket-patch-vendor-<uuid>(file://${project.basedir}/.socket/vendor/maven/<uuid>) and appends it last in<repositories>. The vendored GAV is the original upstream GAV, so it has no suffix. As a result, any repository Maven consults first that also has the GAV wins, and the pristine jar is used.This happens with:
<repository>, for example the company's Central proxy declared in the pom. Maven tries declared repositories in order.settings.xml<mirror><mirrorOf>*</mirrorOf>.*also capturesfile://repositories, so the vendored repo is rerouted to the mirror. (external:*does not capture them, and the vendored repo is honored.)docs/ecosystems.mddocumentsmirrorOf *only for hosted mode, where it fails loudly. In vendored mode it fails open.In both cases,
vendorsucceeds andsocket-patch vex --offlineattestsnot_affected, because the vendored tree, the jar and its.sha1are all intact.Impact
The project is silently unpatched with a positive VEX. Both shapes are common in enterprise builds.
This is the same failure class as the documented warm-
~/.m2shadow, but there is no warning for it. The always-onvendor_maven_local_cache_shadowcovers only the local repository.Repro
The patch is commons-lang3 3.12.0 with a patched
META-INF/NOTICE.txt, set up with a hand-staged.socket/manifest.json+ blob and thenvendor --json --offline, as ine2e_vendor_maven_build. After that:dependency:3.6.1:copy-dependencieswith a fresh local repository.Pom with a pre-existing repository:
After
vendor, the repository order iscorp-proxy, thensocket-patch-vendor-4d5e6f70-….corp-proxydeclared before<mirrorOf>*</mirrorOf><mirrorOf>external:*</mirrorOf>vex --offline --product pkg:maven/com.example/[email protected]in thecorp-proxycase gives exit 0 andnot_affectedforpkg:maven/org.apache.commons/[email protected].Expected vs actual
settings.xmlhas amirrorOfof*, or a pattern matchingsocket-patch-vendor-*. Document*,!socket-patch-vendor-*.CLI revision
3efdc31dSuggested fix
build_repo_edit, anchor on the first wireable<repositories>open tag and insert right after it.vendor_maven_local_cache_shadowfamily with avendor_maven_repository_shadowwarning when other repositories exist.mirrorOf *under vendored.File refs (at 3efdc31)
crates/socket-patch-core/src/vendor/maven_repo.rs:968-985(build_repo_editanchors on</repositories>, i.e. appends)crates/socket-patch-core/src/vendor/maven_repo.rs:1089-1103(repository_block)docs/ecosystems.md:171-186(warm-cache note;mirrorOfnote is hosted-only)