Skip to content

Hosted Maven "redirected" is confirmed by substring, so the scan envelope and ledger claim patches that vex refuses and Maven never enforces #260

Description

[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

For cargo and golang, scan --mode hosted trusts only the rewriter's transactional report (confirmed_cargo_uuids / confirmed_golang_uuids). CLI_CONTRACT says a dep counts as redirected "only when its hosted-artifact URL (or per-dep registry index URL) actually landed in a project file". Maven, however, is confirmed when any final file text merely contains one of:

  • the artifact URL
  • the index URL
  • the suffixed version string

A successful redirect report then writes the ledger record, which the next vex has to reconcile.

Impact

redirected: N and the redirect ledger over-report Maven patches in every case where the pom mentions the suffix or URL without Maven consuming it. Each row below was reproduced with the real CLI; see the linked issues for details.

scenario scan says reality CLI vex
Suffixed version written into an XML comment (commented-out dep) redirected=1 unpatched jar from Central patched_ref_unattributable
Repository injected into an inactive profile or a comment redirected=1 build fails refuses
Rerun after the user deleted the <repository> (and .mvn/), leaving the suffixed pin redirected=1, no edits, no warning build fails (nothing serves the suffix) —
Rerun after only .mvn/ was deleted redirected=1, .mvn/ not restored, no warning Trusted Checksums silently gone attests
Legacy same-GAV grant (no mavenSuffixedVersion) redirected=1 (with redirect_maven_same_gav_fallback) repository only, not fail-closed patched_ref_unattributable (never attested)

The same-GAV row is arguably by design, since it warns. It is listed because the envelope and ledger still count it, while VEX never can.

Repro (the rerun rows, simplest)

  1. scan --mode hosted --json --yes on the basic golden pom (commons-lang3 3.12.0 → 3.12.0-socket.4d5e6f70). Result: redirected=1, 3 files.
  2. Delete the <repositories> block from pom.xml and delete .mvn/.
  3. Run the same scan again. Result: {"redirected":1,"rewrittenFiles":[],"warnings":[],"skipped":[]}. The pom still has no Socket <repository>, and .mvn/ is still absent.

Expected vs actual

  • Expected:
  • Actual: substring confirmation, with no self-heal.

CLI revision

3efdc31d

Suggested fix

  • Add confirmed_maven_uuids to the rewrite result.
  • Set it after the repository insert.
  • Treat an existing suffixed pin as landed for the purpose of (re)inserting the repository and .mvn entries. Today the pin_landed guard skips both on a rerun.
  • Change hosted.rs to use the new set for pkg:maven/ like cargo/golang.

File refs (at 3efdc31)

  • crates/socket-patch-cli/src/commands/scan/hosted.rs:2413-2431 (substring probe incl. suffixed_version.is_some_and(|sv| text.contains(sv)))
  • crates/socket-patch-core/src/patch/redirect/mod.rs:6170-6177 (if !pin_landed { continue; }, so a rerun never re-adds the repository or checksums)
  • crates/socket-patch-cli/CLI_CONTRACT.md:126 (contract text)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions