fix: SSO hardening — OIDC takeover guard, GetSSOLoginURL throttle+GC, SSRF denylist (spec 29 S2/S3/S4)#534
Conversation
… SSRF denylist (spec 29 S2/S3/S4) S2: OIDC auto-link-by-email now refuses to bind an IdP-asserted email to a local PASSWORD account unless the operator delegated identity via TrustEmailAssertions — mirrors the SCIM createUser guard, so a compromised/self-service IdP can't seize a pre-existing credential account. Red-checked. S3: GetSSOLoginURL (public, the most expensive unauth endpoint) joins the rate-limit ladder (per-IP), and CleanupExpiredAuthStates is scheduled hourly so an unauthenticated flood can't grow auth_states unboundedly or amplify outbound OIDC discovery. S4: the OIDC HTTP client gets an SSRF dial-control denylist rejecting loopback, RFC1918/ULA, link-local (incl. 169.254.169.254 metadata), and unspecified addresses — enforced on the resolved dial IP, so a misconfigured/attacker-set issuer/token URL can't probe the internal network. Guard logic unit-tested; a package-var seam disables it for the loopback-backed OIDC integration tests. #533
|
Warning Review limit reached
Next review available in: 58 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: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Filename | Overview |
|---|---|
| internal/idp/linker.go | Adds S2 account-takeover guard: refuses auto-link by email to a local password account unless TrustEmailAssertions is set. Guard correctly short-circuits before Step 3, preventing duplicate-user attempts too. |
| internal/idp/linker_test.go | Adds two new tests pinning the S2 guard: refused auto-link for password accounts without trust, and positive pass-through when TrustEmailAssertions is set. Both use existing mock structure correctly. |
| internal/idp/oidc.go | Adds ssrfSafeDialControl as a net.Dialer.Control hook blocking loopback/RFC1918/ULA/link-local/unspecified/CGNAT addresses after DNS resolution. Package var seam allows test binary to disable the guard for loopback httptest servers. |
| internal/idp/oidc_ssrf_test.go | Unit tests for the SSRF dial-control covering blocked addresses (loopback, RFC1918, link-local, CGNAT, unspecified) and allowed public addresses. Malformed inputs correctly fail closed. |
| internal/idp/main_test.go | TestMain disables the SSRF dial-control for the whole idp test binary so loopback httptest servers remain reachable. Consistent with the existing oidcHTTPTimeout seam pattern. |
| internal/auth/interceptor.go | Adds SSO rate limiter field to RateLimiters and wires the GetSSOLoginURL check before the public-procedures bypass. Ordering is correct: rate check fires first, then the existing public-path handler runs on pass. |
| internal/auth/interceptor_test.go | New test mirrors the ListAuthMethods throttle pattern: 3 requests succeed, the 4th trips ResourceExhausted. Structure is consistent with the existing suite. |
| cmd/control/main.go | Adds CleanupExpiredAuthStates hourly sweep alongside the existing revocation sweep, and registers the SSO rate limiter (10 req/min per IP). Both match existing patterns for periodic tasks and rate limiter wiring. |
Reviews (2): Last reviewed commit: "fix(idp): block RFC 6598 CGNAT (100.64.0..." | Re-trigger Greptile
…Greptile) net.IP.IsPrivate omits shared address space, which is reachable as internal services behind CGNAT / in some cloud VPCs. Added an explicit 100.64.0.0/10 check + test cases. #533
Closes #533. Second-pass audit findings S2/S3/S4 (spec 29).
LinkOrCreateStep 2 refuses to auto-link an IdP-asserted email to a local password account unlessTrustEmailAssertionsis set (mirrors SCIMcreateUserWS5 Release 2026.03 #2). A compromised/self-service IdP can no longer seize a pre-existing credential account. Red-checked.GetSSOLoginURL(public) added to the per-IP rate-limit ladder;CleanupExpiredAuthStatesscheduled hourly. Bounds the storage + outbound-OIDC-discovery DoS.Tests: S2 linker guard (+ positive-when-trusted), S3 throttle (mirrors ListAuthMethods pattern), S4 dial-control unit test (blocked/allowed/malformed). Full idp+auth suites green.