fix: bind credentials to origin and reject TLS downgrade redirects - #2085
Conversation
6e4ce3b to
8564ef1
Compare
|
LGTM, and a Q: URL transport does not need any change? |
gnodet
left a comment
There was a problem hiding this comment.
Excellent security hardening across all three HTTP transports with comprehensive test coverage. The credential binding and TLS downgrade rejection are correctly implemented.
⚠️ @since tag corrections (12 locations)
All 12 @since tags across the PR say 2.0.22, but that version is already released (tag exists). They must be updated to @since 2.0.23 to match the milestone. Affected files:
RemoteRepositoryManager.java(1)DefaultRemoteRepositoryManager.java(1)ApacheTransporterConfigurationKeys.java(2)OriginScopedHeadersInterceptor.java(1)ResolverRedirectStrategy.java(1)JdkTransporterConfigurationKeys.java(2)JettyTransporterConfigurationKeys.java(2)InsecureRedirectGuard.java(1)OriginScopedHeadersListener.java(1)
Minor observations (not blocking)
- JDK transport redirect error quality: When
followableRedirect()returns null on HTTPS→HTTP downgrade, the raw 302 is returned, producing a genericHttpTransporterException(302). Apache's equivalent throwsProtocolExceptionwith an explicit message naming the config property. Consider matching the error quality for parity. effectivePortduplication: 5 near-identical implementations across modules. Cross-module dedup is constrained by different HTTP APIs, but within-module consolidation (Apache: 2 copies, JDK: 2 copies) is feasible.
Positive observations
- Credential scoping by scheme+host+port is correct across all transports
- Fail-closed on unknown target host
- Case-insensitive hostname and header comparisons
- Default port normalization prevents port-mismatch bypasses
- Descriptor-repository credential blocking correctly allows mirrored repos
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
|
@cstamas — good question. The URL transport (
These were already part of the URL transport's redirect handling prior to this PR. The three transports that needed fixing were:
The URL transport was already doing the right thing here. |
Add OriginScopedHeadersListener to confine preemptive Authorization and user-configured HTTP headers to the repository origin so a cross-origin redirect does not replay them to the target host. The listener is only registered when there are actual credentials or configured headers to protect — challenge-based authentication from Jetty's auth store is already URI-scoped. Add InsecureRedirectGuard (QueuedListener) to abort any request whose URI is non-HTTPS when the repository was configured with HTTPS, preventing TLS-downgrade redirect attacks. Both guards are registered as client-level request listeners so they also fire on copied redirect requests created by Jetty's redirector. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.0.22 is already released; new API additions must target 2.0.23. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
134f538 to
fe20051
Compare
Summary
Fixes 5 findings from the maven-resolver security audit (scan-maven-resolver-20260811):
Root cause: Credential release decisions ignore where the request is actually going: selectors match on bare repository id with no host binding, authenticators answer any challenger, redirect handling follows cross-origin and https-to-http hops.
Fix: Enforce one rule across all transports: credentials go only to the configured origin, and https never silently becomes http.
Test plan
🤖 Generated with Claude Code