[agent] Found by the scheduled Maven bug-hunt routine (ledger #318).
Summary
vendor writes the committed maven2 tree .socket/vendor/maven/<uuid>/… with only <file>.sha1 sidecars, and wires it as a file:// <repository> with checksumPolicy=fail. Projects that harden Maven's checksums by setting the resolver's aether.checksums.algorithms to SHA-256 and/or SHA-512 without SHA-1 (via -D… or .mvn/maven.config) get this:
- Maven 3.8.8 / 3.9.11: the vendored repo has no checksum in the configured algorithms, so the
fail policy rejects it with no warning at all. The resolver moves on to Central, which is under the default warn policy, and downloads the pristine jar. BUILD SUCCESS, exit 0, unpatched bytes.
- Maven 4.0.0-rc-7: the build fails with
Could not transfer artifact … from/to socket-patch-vendor-<uuid> … Checksum validation failed, no checksums available. That is fail-closed, but vendoring breaks a build that worked before.
vex (online or --offline) on the fresh checkout still emits not_affected / inline_mitigations_already_exist "(vendored)". It prints a stderr warning that the live tree differs, but still makes the attestation.
Impact
Users who opt into SHA-256/512-only checksums are the most security-conscious ones, and for them the vendored patch is silently skipped while VEX says it's applied. Nothing in socket-patch's or Maven's output flags it.
Repro (Linux, JDK 21, Maven 3.9.11)
- Consumer
pom.xml depends on org.apache.commons:commons-text:1.10.0. Warm a fresh -Dmaven.repo.local.
- Stage
.socket/manifest.json + blob: a patch that appends a marker to META-INF/NOTICE.txt, with real git-sha256 before/after hashes (the same shape as crates/socket-patch-cli/tests/e2e_vendor_maven_build.rs::stage_manifest).
- Run
socket-patch vendor --json --offline --cwd proj. It reports applied: 1 and wires file://${project.basedir}/.socket/vendor/maven/<uuid> with checksumPolicy=fail.
- Fresh checkout: delete the manifest and blobs, and purge
org/apache/commons/commons-text from the local repo.
echo '-Daether.checksums.algorithms=SHA-256,SHA-512' > proj/.mvn/maven.config
mvn -B -Dmaven.repo.local=$M2 org.apache.maven.plugins:maven-dependency-plugin:3.1.2:copy-dependencies, then check target/dependency/commons-text-1.10.0.jar for the marker.
Log (3.9.11): one Downloading from socket-patch-vendor-… line, with no WARN/ERROR for it, followed by
[INFO] Downloading from central: …/commons-text-1.10.0.jar
[WARNING] Checksum validation failed, no checksums available from central for …/commons-text-1.10.0.jar
[INFO] Downloaded from central: …/commons-text-1.10.0.jar (238 kB)
BUILD SUCCESS
The jar is PRISTINE. Adding commons-text-1.10.0.{jar,pom}.sha256 + .sha512 sidecars by hand to the vendored leaf makes the same run resolve PATCHED, which confirms the root cause and the fix direction.
Expected vs actual
- Expected: docs/ecosystems.md (Maven row) and the
maven_repo.rs module docs say the committed repo is consumed with checksumPolicy=fail, so that "a tampered jar → checksum failure", and vendored mode must never fall through to the registry silently. The vendored repo should satisfy whichever checksum algorithms Maven is configured for, e.g. by writing .sha256 and .sha512 (and optionally .md5) next to .sha1.
- Actual: the vendored repo can be validated with SHA-1 only. Under a non-SHA-1 algorithm set it is skipped without a sound, and
vex attests anyway.
Matrix (Linux, JDK 21; resolve with maven-dependency-plugin 3.1.2, fresh local repo)
| Maven |
default |
SHA-512 |
SHA-256 |
SHA-512,SHA-1 |
| 3.6.3 |
PATCHED |
PATCHED (property ignored) |
PATCHED |
PATCHED |
| 3.8.8 |
PATCHED |
PRISTINE, exit 0 |
PRISTINE, exit 0 |
PATCHED |
| 3.9.11 |
PATCHED |
PRISTINE, exit 0 (reproduced 3×, via -D and .mvn/maven.config) |
PRISTINE, exit 0 |
PATCHED |
| 4.0.0-rc-7 |
PATCHED |
build fails on the vendored repo |
build fails on the vendored repo |
PATCHED |
macOS and Windows are untested. The behaviour is resolver-level, so it's expected to match.
Not bisected: every release that has vendored Maven writes .sha1 only (main f6b7fb9, 4.0.0).
Suspect code
crates/socket-patch-core/src/vendor/maven_repo.rs:1015-1037 (write_maven_artifact writes only .sha1)
crates/socket-patch-core/src/vendor/maven_repo.rs:23-30 (the design note says sha1 alone is enough)
maven_repo.rs:1050-1080: the verify/re-run fast path also checks .sha1 only, so new sidecars would need to join it.
[agent] Found by the scheduled Maven bug-hunt routine (ledger #318).
Summary
vendorwrites the committed maven2 tree.socket/vendor/maven/<uuid>/…with only<file>.sha1sidecars, and wires it as afile://<repository>withchecksumPolicy=fail. Projects that harden Maven's checksums by setting the resolver'saether.checksums.algorithmstoSHA-256and/orSHA-512withoutSHA-1(via-D…or.mvn/maven.config) get this:failpolicy rejects it with no warning at all. The resolver moves on to Central, which is under the defaultwarnpolicy, and downloads the pristine jar.BUILD SUCCESS, exit 0, unpatched bytes.Could not transfer artifact … from/to socket-patch-vendor-<uuid> … Checksum validation failed, no checksums available. That is fail-closed, but vendoring breaks a build that worked before.vex(online or--offline) on the fresh checkout still emitsnot_affected/inline_mitigations_already_exist"(vendored)". It prints a stderr warning that the live tree differs, but still makes the attestation.Impact
Users who opt into SHA-256/512-only checksums are the most security-conscious ones, and for them the vendored patch is silently skipped while VEX says it's applied. Nothing in socket-patch's or Maven's output flags it.
Repro (Linux, JDK 21, Maven 3.9.11)
pom.xmldepends onorg.apache.commons:commons-text:1.10.0. Warm a fresh-Dmaven.repo.local..socket/manifest.json+ blob: a patch that appends a marker toMETA-INF/NOTICE.txt, with real git-sha256 before/after hashes (the same shape ascrates/socket-patch-cli/tests/e2e_vendor_maven_build.rs::stage_manifest).socket-patch vendor --json --offline --cwd proj. It reportsapplied: 1and wiresfile://${project.basedir}/.socket/vendor/maven/<uuid>withchecksumPolicy=fail.org/apache/commons/commons-textfrom the local repo.echo '-Daether.checksums.algorithms=SHA-256,SHA-512' > proj/.mvn/maven.configmvn -B -Dmaven.repo.local=$M2 org.apache.maven.plugins:maven-dependency-plugin:3.1.2:copy-dependencies, then checktarget/dependency/commons-text-1.10.0.jarfor the marker.Log (3.9.11): one
Downloading from socket-patch-vendor-…line, with no WARN/ERROR for it, followed byThe jar is PRISTINE. Adding
commons-text-1.10.0.{jar,pom}.sha256+.sha512sidecars by hand to the vendored leaf makes the same run resolve PATCHED, which confirms the root cause and the fix direction.Expected vs actual
maven_repo.rsmodule docs say the committed repo is consumed withchecksumPolicy=fail, so that "a tampered jar → checksum failure", and vendored mode must never fall through to the registry silently. The vendored repo should satisfy whichever checksum algorithms Maven is configured for, e.g. by writing.sha256and.sha512(and optionally.md5) next to.sha1.vexattests anyway.Matrix (Linux, JDK 21; resolve with maven-dependency-plugin 3.1.2, fresh local repo)
SHA-512SHA-256SHA-512,SHA-1-Dand.mvn/maven.config)macOS and Windows are untested. The behaviour is resolver-level, so it's expected to match.
Not bisected: every release that has vendored Maven writes
.sha1only (mainf6b7fb9, 4.0.0).Suspect code
crates/socket-patch-core/src/vendor/maven_repo.rs:1015-1037(write_maven_artifactwrites only.sha1)crates/socket-patch-core/src/vendor/maven_repo.rs:23-30(the design note says sha1 alone is enough)maven_repo.rs:1050-1080: the verify/re-run fast path also checks.sha1only, so new sidecars would need to join it.