Security concerns around SSO and Account Opening Flows
SAML Security Concerns
Threat Model
User starts at Web App A → triggers SAML SSO to Web App B (SP) via IdP → user opens an account at B → redirected back to A.
SAML Assertions & Protocol
Signatures everywhere
- Require XMLDSig on the Assertion (and ideally the entire Response) using strong algorithms (RSA-SHA256+).
- Reject
alg:none, outdated digests, or unsigned responses.
Audience & recipient checks
- Validate
AudienceRestriction→ must match B’s entityID. - Validate
Recipienton theSubjectConfirmationData→ must equal B’s ACS URL.
Replay protection
- Enforce
NotBefore/NotOnOrAfterwith small clock skew. - Cache Assertion IDs and reject replays (e.g., 5–15 minute window).
InResponseTo binding
- SP-initiated: check
InResponseTomatches your outstanding AuthnRequest ID. - IdP-initiated: treat as lower assurance (no
InResponseTo)—consider requiring step-up before sensitive actions.
NameID & attributes
- Prefer persistent NameID (or a stable pair like issuer + NameID). Don’t link accounts on email alone.
- Encrypt sensitive attributes and/or the whole assertion (SAML encryption).
RequestedAuthnContext & step-up
- Set
RequestedAuthnContext(e.g., MFA) and verifyAuthnContextClassRefin the assertion. - For “account opening,” perform step-up MFA at B if prior assurance is insufficient.
Bindings & Endpoints
Bindings choice
- Use HTTP-Redirect (deflate-signed) for AuthnRequest from B → IdP.
- Use HTTP-POST for IdP → B Response (keeps long, signed assertions intact).
- Consider Artifact binding if you want to keep assertions out of the browser.
ACS URLs & strict allowlisting
- Register exact ACS URLs in IdP metadata; no wildcards.
- B must reject assertions delivered to unexpected ACS endpoints.
RelayState & Post-Login Navigation
RelayState integrity
- Treat RelayState as untrusted input; bind it to the SP session or HMAC it.
- Don’t let RelayState become an open redirect—allowlist destinations.
Return to A
- If B sends a “success” signal back to A, use a signed, short-lived token (JWT or opaque mapped server-side) rather than query flags.
- A must verify signature/audience/expiry before trusting “account opened”.
XML-Level Pitfalls
XML wrapping & reference attacks
- Use a well-vetted SAML library; validate that the signed element is the one you actually process.
XXE
- Disable external entity resolution in your XML parser.
Keys, Metadata, & Rollover
Metadata hygiene
- Pull IdP/SP metadata over HTTPS; pin entityID and expected certificate fingerprints.
Key rotation
- Honor
kid/cert rollover; maintain overlapping trusted keys during rotation windows.
Sessions, Cookies, & CSRF at B
- Session fixation: regenerate session on SSO; set cookies
Secure,HttpOnly,SameSite(None; Secureonly when truly cross-site). - CSRF on account-creation: require CSRF token (or SameSite protection), check Origin/Referer, and use idempotency keys to prevent duplicate account creation.
- Clickjacking:
Content-Security-Policy: frame-ancestors 'none'.
Authorization to B’s API
- If the browser calls B: safeguard with CSRF + user session at B.
- If A calls B (server-side): do not repurpose the user’s SAML assertion. Use a separate channel (e.g., OAuth2 client credentials) and bind requests to the user’s identity via a signed result from B. Avoid the confused-deputy problem.
Logging & Privacy
- No secrets/PII in logs: don’t log full SAML responses or URLs.
- Attribute minimization: request only what B needs for account opening; avoid passing sensitive PII through A if possible.
Quick, Copy-Paste Checklist
- IdP → B SAML Response & Assertion signed; audience/recipient validated
- NotBefore/NotOnOrAfter checked; replay cache enabled
- InResponseTo validated (SP-initiated); IdP-initiated guarded with step-up
- Persistent identifier used for account linking; encrypted attributes for PII
- AuthnContext (MFA) requested and verified before account creation
- HTTP-POST for Response; exact ACS allowlist; safe RelayState
- XML parser hardened (no XXE); signature wrapping protections in place
- Session regeneration; cookies Secure/HttpOnly/SameSite; CSRF on creation endpoint
- IdP/SP metadata over HTTPS; cert pinning & key rollover handled
- Clear, signed success signal from B → A; no open redirects
- Minimal attributes; redacted logs