Skip to content

Validate metadata inputs and honour checksum policy on legacy paths - #13002

Merged
gnodet merged 1 commit into
maven-3.9.xfrom
pr/legacy-compat-3.9.x
Sep 1, 2026
Merged

Validate metadata inputs and honour checksum policy on legacy paths#13002
gnodet merged 1 commit into
maven-3.9.xfrom
pr/legacy-compat-3.9.x

Conversation

@gnodet

@gnodet gnodet commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Backport of the path traversal validation and checksum policy fixes from #12950 (master) / #12945 (maven-4.0.x) / #12978 (maven-3.10.x) to the maven-3.9.x branch.

Path traversal validation

  • Repository key validation. AbstractRepositoryMetadata.getLocalFilename() and LegacyLocalRepositoryManager.ArtifactMetadataAdapter.getLocalFilename() now reject a repository key that is .., contains /, \, :, or an ISO control character before using it in a local file name.
  • Version token validation in metadata. DefaultRepositoryMetadataManager.readMetadata() validates every version token carried by parsed repository metadata (latest, release, versions, snapshot versions, snapshot timestamp) for the same path traversal characters.

Checksum policy enforcement

  • DefaultRepositoryMetadataManager.resolve() now catches ChecksumFailedException separately and fails metadata resolution under checksumPolicy=fail instead of downgrading to a warning. The update-check file is only touched on success, not-found, or generic transfer failure, so checksum failures are retried on the next build.
  • getArtifactMetadataFromDeploymentRepository() resolves the effective policy from the repository configuration instead of hardcoding warn.
  • LegacyRepositorySystem.retrieve() resolves the effective policy from the repository configuration (stricter of release/snapshot) instead of hardcoding warn.

The proxy clone fix (DefaultSettingsDecrypter) is not included because 3.9.x already clones each proxy before decryption.

Adapted for the 3.9.x module structure (no compat/ prefix, AbstractRepositoryMetadata in maven-core, MetadataXpp3Reader instead of MetadataStaxReader, no instanceof pattern matching).

Test plan

  • AbstractRepositoryMetadataTest (4 tests): repo keys with /, \, .., : are rejected; well-formed key produces correct filename
  • LegacyLocalRepositoryManagerTest (3 tests): repo keys with path separators and .. are rejected in the inner adapter
  • DefaultRepositoryMetadataManagerValidationTest (2 tests): metadata with invalid version token (colon) and invalid snapshot timestamp (colon) are rejected
  • DefaultRepositoryMetadataManagerTest (1 test): resolve() throws RepositoryMetadataResolutionException when checksum policy is fail and checksums do not match
  • LegacyRepositorySystemTest.testRetrieveHonorsConfiguredFailChecksumPolicy: retrieve() throws ArtifactTransferFailedException when checksum policy is fail
  • mvn test -pl maven-core passes
  • mvn test -pl maven-compat passes

🤖 Generated with Claude Code

…policy

Backport of the path traversal validation and checksum policy fixes from
#12950 (master) / #12945 (maven-4.0.x) / #12978 (maven-3.10.x) to the
maven-3.9.x branch.

- Path traversal: AbstractRepositoryMetadata.getLocalFilename() and
  LegacyLocalRepositoryManager.ArtifactMetadataAdapter.getLocalFilename()
  now reject repository keys containing '..', '/', '\', ':', or ISO
  control characters.

- Metadata token validation: DefaultRepositoryMetadataManager.readMetadata()
  validates every version token (latest, release, versions, snapshot
  versions, snapshot timestamp) for the same characters after parsing.

- Checksum policy: resolve() now catches ChecksumFailedException
  separately and fails metadata resolution under checksumPolicy=fail.
  getArtifactMetadataFromDeploymentRepository() and
  LegacyRepositorySystem.retrieve() resolve the effective policy from
  the repository configuration instead of hardcoding 'warn'.

The proxy clone fix (DefaultSettingsDecrypter) is not included because
3.9.x already clones each proxy before decryption.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet marked this pull request as ready for review September 1, 2026 12:37
@gnodet gnodet added this to the 3.9.17 milestone Sep 1, 2026
@gnodet gnodet added the bug Something isn't working label Sep 1, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, faithful backport of security hardening (path traversal validation and checksum policy enforcement) to the maven-3.9.x legacy compat layer. All adaptations for the 3.9.x module structure are correct; no logic drift from the source PRs.

Two low-severity observations (both already noted in the upstream #12945 review):

  1. Code duplicationisInvalidPathToken/validateRepositoryKey are duplicated verbatim between AbstractRepositoryMetadata (maven-core) and LegacyLocalRepositoryManager.ArtifactMetadataAdapter (maven-core). Both are in the same module and could share a package-private utility. Acceptable for deprecated compat code and consistent with the upstream PRs.

  2. Update tracker inconsistency on deployment pathgetArtifactMetadataFromDeploymentRepository still touches the update tracker in its finally block, meaning a ChecksumFailedException (now possible with the newly configurable policy) will mark the metadata as checked and suppress retry for the full update interval. This contrasts with resolve() which deliberately skips the touch on checksum failure. Low severity because the deployment path is not retry-sensitive in the same way as resolution.

📋 PR Metadata

Aspect Current Suggested
Category (unlabeled) bug
Labels (none) + bug
Milestone (none) 3.9.17

🔀 Backport Status

✅ This PR is the 3.9.x backport. All maintenance branches are covered:

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@gnodet
gnodet merged commit 1802f2e into maven-3.9.x Sep 1, 2026
22 checks passed
@gnodet
gnodet deleted the pr/legacy-compat-3.9.x branch September 1, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant