Repository navigation
fix: prevent remote signals from weakening operator-configured policy - #2082
Conversation
47ba3c6 to
00f50bb
Compare
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
00f50bb to
5fd1601
Compare
gnodet
left a comment
There was a problem hiding this comment.
The five security audit fixes (f011, f012, f014, f015, f018) are all correctly implemented with sound logic, thorough test coverage, and opt-out configuration properties for each behavioral change.
@since tag corrections (4 locations)
All new constants and the site documentation reference 2.0.22, but that version is already released (tag exists). These should be @since 2.0.23:
DefaultRemoteRepositoryManager.javaline 185:CONFIG_PROP_RAW_CHECKSUM_POLICY_DOWNGRADEDefaultRemoteRepositoryManager.javaline 292:CONFIG_PROP_NATURE_MERGE_WEAKEST_CHECKSUM_POLICYPrefixesRemoteRepositoryFilterSource.javaline 247:CONFIG_PROP_VERIFY_DENIED_DROPS_TREEremote-repository-filtering.mdline 222: "since 2.0.22" β "since 2.0.23"
Minor: duplicate helper methods
checksumPolicyRank() (lines 219-235) and checksumPolicyStrength() (lines 425-441) in DefaultRemoteRepositoryManager.java have identical implementations β same switch, same return values. Could be consolidated into a single method to reduce maintenance risk from future drift.
Positive observations
- Each fix has an opt-out configuration property that restores legacy behavior β right pattern for security hardening
- Thread safety of
CachedPrefixes.verifiedServedPathis properly handled (volatile + synchronized) - The refactoring of
repositoriesEquals()from private ConstraintKey to a shared utility is clean - Test coverage is thorough: default behavior, legacy opt-out, and edge cases for each fix
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
2.0.22 is already released; new API additions must target 2.0.23. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gnodet
left a comment
There was a problem hiding this comment.
Re-reviewed after the @since tag correction β the tags are now correctly set to 2.0.23 throughout.
The security hardening itself remains solid:
- Checksum policy clamping prevents remote metadata from downgrading operator-configured verification
- Repository-scoped descriptor cache stops poisoned POM resolution from being replayed across repository contexts
- Resilient prefix filter no longer drops the entire dependency-confusion guard on a single remote probe
- Each fix is gated behind a configuration property with secure defaults and backwards-compatible opt-in for legacy behavior
Test coverage is comprehensive. No new issues introduced by the follow-up commits.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
Description Fixes the Maven Resolver prefix filter behavior when a repository serves an artifact path that is missing from its "prefixes.txt". A repository such as an Artifactory/Nexus virtual repository may expose a prefixes file generated from a public repository index while also serving private/internal artifacts. When the requested artifact path is absent from that prefixes file, the prefix filter can reject an artifact that the repository actually serves. This change verifies a denied path against the repository before permanently rejecting it. Implementation - Successfully served denied paths are cached and allowed on subsequent requests. - Definitively absent paths remain blocked and are negative-cached to avoid repeated remote probes. - Transient/unknown transport failures are not negative-cached, allowing later requests to retry. - Verification is performed per exact artifact path. - Multiple independently denied paths can be verified without disabling the repository's prefix filter globally. - Existing "verifyDeniedDropsTree=true" legacy behavior remains unchanged. Security The implementation preserves the security invariant introduced by Resolver PR #2082. A successful verification of one denied path does NOT disable the prefix filter for the entire repository or authorize unrelated artifact paths. Only the exact remotely verified path is allowed. Tests - "PrefixesRemoteRepositoryFilterSourceVerifyDeniedTest": 14/14 passed - "PrefixesRemoteRepositoryFilterSourceTest": 6/6 passed - Checkstyle: passed with 0 violations - Spotless: passed - "git diff --check": clean Related Maven Issue This addresses the underlying Maven Resolver behavior reported in Apache Maven issue #13385: apache/maven#13385 The original issue is reported against Maven because Maven users experience the resolution failure, while the prefix filtering implementation itself lives in Maven Resolver.
Summary
Fixes 5 findings from the maven-resolver security audit (scan-maven-resolver-20260811):
Root cause: Policy merges, filter state, negative caches, and the descriptor cache all accept remotely-influenced input as authoritative, allowing hostile POMs to silently weaken operator-configured verification controls.
Fix: Input from a remote repository must never weaken an operator-configured verification or filtering decision. Merge strongest-wins, include repository context in cache keys, allow only verified paths instead of dropping filters.
Test plan
π€ Generated with Claude Code