Skip to content

Fix authentication bypass with AllowIDPInitiated#659

Open
aashh wants to merge 1 commit intocrewjam:mainfrom
aashh:fix/issue-03
Open

Fix authentication bypass with AllowIDPInitiated#659
aashh wants to merge 1 commit intocrewjam:mainfrom
aashh:fix/issue-03

Conversation

@aashh
Copy link

@aashh aashh commented Feb 9, 2026

When AllowIDPInitiated is true, InResponseTo validation is skipped at both the Response and Assertion levels - even for SP-initiated flows that have an InResponseTo value. This allows replay attacks against SPs that enable IdP-initiated SSO.

The validation logic treated AllowIDPInitiated as "skip all InResponseTo checks" rather than "allow empty InResponseTo for unsolicited responses."

Fix: Only skip InResponseTo validation when both conditions are met: (1) InResponseTo is empty (genuinely unsolicited) and (2) AllowIDPInitiated is true. When InResponseTo is present and non-empty, validate it against tracked request IDs regardless of the AllowIDPInitiated flag.

Some IdPs (notably Rippling) set InResponseTo to arbitrary values in IdP-initiated flows. Users can handle this with the existing ValidateRequestID hook.

Changes:

  • service_provider.go: Fix validation logic in validateAssertion and parseResponse
  • service_provider_test.go: Add TestSPValidateRequestIDWithAllowIDPInitiated

Testing:

  • AllowIDPInitiated=true, InResponseTo="": accepted (IdP-initiated)
  • AllowIDPInitiated=true, InResponseTo="wrong-id": rejected (replay attack blocked)
  • AllowIDPInitiated=true, InResponseTo="valid-id": accepted (SP-initiated works)
  • AllowIDPInitiated=false: existing behavior preserved

Fixes aashh#3

Previously, when AllowIDPInitiated was true, InResponseTo was
completely skipped at both the Response and SubjectConfirmation
levels. This allowed replay of assertions with arbitrary
InResponseTo values.

Now, InResponseTo is only skipped when it is empty AND
AllowIDPInitiated is true (a genuine IDP-initiated flow). When
InResponseTo is present and non-empty, it is validated against
tracked request IDs regardless of AllowIDPInitiated.

IDPs that set InResponseTo to arbitrary values in IDP-initiated
flows (e.g. Rippling) can use the existing ValidateRequestID
hook to customize this behavior.

Fixes #3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InResponseTo not validated when AllowIDPInitiated is set

1 participant