fix(scheduledauth): use hardened HTTP client for JWKS warmup and fetch - #1231
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 37 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Adversarial review (PR #1231)Reviewed against the six risk surfaces from the brief (IMDS/SSRF blocking, JWKS URL validation, ctx-aware warmup, fail-closed semantics, refresh path uses hardened transport, PII/key material in logs). One canonical-vs-textual IMDS bypass found and fixed in this push; three follow-ups filed for the larger SSRF / scheme-enforcement / fail-closed-warmup work that was deliberately out of scope for SEC-04. Verified
Fix pushed (a8c5315)
Switched to Test suite delta: Out-of-scope, filed as follow-ups
UNSTABLE state
VerdictLGTM with the canonical-form fix applied. Re-pinging |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
✏️ Learnings added
✅ Action performedReview finished.
|
The scheduled-task OIDC validator issued its JWKS warmup probe via http.DefaultClient and let go-oidc's RemoteKeySet fetch keys over the default transport. The JWKS URL is operator-supplied (SCHEDULED_TASK_OIDC_JWKS_URL), so a misconfigured or compromised value could reach internal/metadata endpoints, bypassing the IMDS-blocking hardening the Azure provider clients already use. Move the hardened client (IMDS blocking, dial/TLS/overall timeouts) from providers/azure/internal/httpclient to the shared pkg/httpclient package, since the Azure-internal package is unimportable across the module boundary; the Azure package now delegates to it so there is a single implementation. The validator constructs this client once in configureOIDC, uses it for the warmup probe, and supplies it to go-oidc via oidc.ClientContext so key fetches and rotation refreshes ride the same hardened transport. Regression tests guard all paths: the constructed client must not be http.DefaultClient and must carry a timeout and dedicated transport; Warmup and token-verification key fetches are run with a guarded http.DefaultClient that fails the test if used (both fail pre-fix); pkg/httpclient gets direct IMDS-blocking coverage (IPv4 + IPv6). Closes #1145
|
@coderabbitai review |
✅ Action performedReview finished.
|
gosec's taint analysis flags v.httpClient.Do(req) because v.jwksURL comes from operator-supplied configuration (SCHEDULED_TASK_OIDC_JWKS_URL). The call is safe: jwksURL is operator config, not request-tainted user input, and v.httpClient is the hardened client from pkg/httpclient that blocks IMDS/link-local endpoints and enforces dial/TLS/overall timeouts. Add #nosec G704 with a full justification naming both guards.
|
@coderabbitai review |
✅ Action performedReview finished.
|
Problem
SEC-04 (docs/reviews/codebase-review-2026-06-10.md): the scheduled-task OIDC validator's
Warmupprobed the JWKS endpoint viahttp.DefaultClient, andoidc.NewRemoteKeySetfetched keys over go-oidc's default transport. The JWKS URL is operator-supplied (SCHEDULED_TASK_OIDC_JWKS_URL, validated only as an absolute URL), so a misconfigured or compromised value could reach internal/metadata endpoints, bypassing the IMDS-blocking hardening already mandatory for Azure provider clients.Fix
pkg/httpclientpackage hosting the hardened client (IMDS blocking for IPv4169.254.169.254and IPv6fd00:ec2::254, dial/TLS/overall timeouts as named constants). The previous home,providers/azure/internal/httpclient, is unimportable from the root module across the module boundary; it now delegates to the shared package so there is a single implementation and the existinghttpclient.New()convention inproviders/azure/is unchanged.internal/server/scheduledauth:configureOIDCconstructs the hardened client once,Warmupuses it for the probe, and it is supplied to go-oidc viaoidc.ClientContextso key fetches and rotation refreshes ride the same hardened transport. No caller-supplied client exists on this path, so nothing is clobbered.Test evidence
TestWarmup_BypassesDefaultClientandTestValidate_OIDC_KeyFetchBypassesDefaultClientinstall a guardedhttp.DefaultClientthat fails the test if any JWKS traffic flows through it; pre-fix both fail (Warmup made 1 request(s) through http.DefaultClient, key fetch rejected), post-fix both pass with the JWKS test server actually reached.TestNew_OIDC_UsesHardenedHTTPClientasserts the constructed client is nothttp.DefaultClient, has a timeout, and does not ridehttp.DefaultTransport.pkg/httpclienttests: not-default-client guard, IMDS blocking (IPv4 + IPv6), and a non-IMDS endpoint still allowed.go build ./...green in root,pkg/, andproviders/azure/modules;go vetclean on touched packages.go test ./internal/server/scheduledauth/...(54 passed),pkg:go test ./...(448 passed),providers/azure:go test ./...(696 passed).Closes #1145