Skip to content

fix: prevent remote signals from weakening operator-configured policy - #2082

Merged
cstamas merged 3 commits into
masterfrom
security/remote-signal-policy-weakening
Aug 31, 2026
Merged

fix: prevent remote signals from weakening operator-configured policy#2082
cstamas merged 3 commits into
masterfrom
security/remote-signal-policy-weakening

Conversation

@gnodet

@gnodet gnodet commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes 5 findings from the maven-resolver security audit (scan-maven-resolver-20260811):

Finding Severity Description
f011 MEDIUM Metadata checksum policy silently downgraded by release/snapshot weakest-wins merge
f012 MEDIUM Descriptor cache ignores repository context: poisoned POM resolution replayed build-wide
f014 MEDIUM Single remote probe drops the entire prefixes dependency-confusion filter
f015 MEDIUM Remote POM repository declaration downgrades mirror checksum policy to ignore
f018 MEDIUM Cached not-found converts transient denial into persistent source rerouting

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

  • Existing tests pass
  • Checksum policy merge uses strongest-wins
  • Descriptor cache is repository-aware
  • Prefixes filter does not drop to accept-all on single probe

🤖 Generated with Claude Code

@gnodet
gnodet force-pushed the security/remote-signal-policy-weakening branch from 47ba3c6 to 00f50bb Compare August 30, 2026 19:35
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the security/remote-signal-policy-weakening branch from 00f50bb to 5fd1601 Compare August 30, 2026 20:00
@gnodet
gnodet marked this pull request as ready for review August 31, 2026 05:20
@gnodet
gnodet requested a review from cstamas August 31, 2026 05:20
@gnodet gnodet added bug Something isn't working priority:major Major loss of function labels Aug 31, 2026
@gnodet gnodet added this to the 2.0.23 milestone Aug 31, 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.

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.java line 185: CONFIG_PROP_RAW_CHECKSUM_POLICY_DOWNGRADE
  • DefaultRemoteRepositoryManager.java line 292: CONFIG_PROP_NATURE_MERGE_WEAKEST_CHECKSUM_POLICY
  • PrefixesRemoteRepositoryFilterSource.java line 247: CONFIG_PROP_VERIFY_DENIED_DROPS_TREE
  • remote-repository-filtering.md line 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.verifiedServedPath is 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 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.

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

gnodet added a commit to gnodet/maven-resolver that referenced this pull request Aug 31, 2026
@cstamas
cstamas merged commit 55252d5 into master Aug 31, 2026
24 checks passed
@cstamas
cstamas deleted the security/remote-signal-policy-weakening branch August 31, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority:major Major loss of function

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants