Skip to content

Commit 873309e

Browse files
committed
Stop validating InResponseTo when AllowIDPInitiated is set
With this change we no longer validate InResponseTo when AllowIDPInitiated is set. Here's why: The SAML specification does not provide clear guidance for handling InResponseTo for IDP-initiated requests where there is no request to be in response to. The specification says: InResponseTo [Optional] The ID of a SAML protocol message in response to which an attesting entity can present the assertion. For example, this attribute might be used to correlate the assertion to a SAML request that resulted in its presentation. The initial thought was that we should specify a single empty string in possibleRequestIDs for IDP-initiated requests so that we would ensure that an InResponseTo was *not* provided in those cases where it wasn't expected. Even that turns out to be frustrating for users. And in practice some IDPs (e.g. Rippling) set a specific non-empty value for InResponseTo in IDP-initiated requests. Finally, it is unclear that there is significant security value in checking InResponseTo when we allow IDP initiated assertions. This issue has been reported quite a few times, including: Fixes #291 #286 #300 #301 #286
1 parent 6614c51 commit 873309e

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

service_provider.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -717,14 +717,34 @@ func (sp *ServiceProvider) validateAssertion(assertion *Assertion, possibleReque
717717
}
718718
for _, subjectConfirmation := range assertion.Subject.SubjectConfirmations {
719719
requestIDvalid := false
720-
for _, possibleRequestID := range possibleRequestIDs {
721-
if subjectConfirmation.SubjectConfirmationData.InResponseTo == possibleRequestID {
722-
requestIDvalid = true
723-
break
720+
721+
// We *DO NOT* validate InResponseTo when AllowIDPInitiated is set. Here's why:
722+
//
723+
// The SAML specification does not provide clear guidance for handling InResponseTo for IDP-initiated
724+
// requests where there is no request to be in response to. The specification says:
725+
//
726+
// InResponseTo [Optional]
727+
// The ID of a SAML protocol message in response to which an attesting entity can present the
728+
// assertion. For example, this attribute might be used to correlate the assertion to a SAML
729+
// request that resulted in its presentation.
730+
//
731+
// The initial thought was that we should specify a single empty string in possibleRequestIDs for IDP-initiated
732+
// requests so that we would ensure that an InResponseTo was *not* provided in those cases where it wasn't
733+
// expected. Even that turns out to be frustrating for users. And in practice some IDPs (e.g. Rippling)
734+
// set a specific non-empty value for InResponseTo in IDP-initiated requests.
735+
//
736+
// Finally, it is unclear that there is significant security value in checking InResponseTo when we allow
737+
// IDP initiated assertions.
738+
if !sp.AllowIDPInitiated {
739+
for _, possibleRequestID := range possibleRequestIDs {
740+
if subjectConfirmation.SubjectConfirmationData.InResponseTo == possibleRequestID {
741+
requestIDvalid = true
742+
break
743+
}
744+
}
745+
if !requestIDvalid {
746+
return fmt.Errorf("assertion SubjectConfirmation one of the possible request IDs (%v)", possibleRequestIDs)
724747
}
725-
}
726-
if !requestIDvalid {
727-
return fmt.Errorf("assertion SubjectConfirmation one of the possible request IDs (%v)", possibleRequestIDs)
728748
}
729749
if subjectConfirmation.SubjectConfirmationData.Recipient != sp.AcsURL.String() {
730750
return fmt.Errorf("assertion SubjectConfirmation Recipient is not %s", sp.AcsURL.String())

0 commit comments

Comments
 (0)