Skip to content

Commit 93d07ad

Browse files
jasiekcrewjam
authored andcommitted
(Add tests for) Destination is checked only if this is a signed SAML request, as that is the only case in which a Destination attribute is required.
1 parent 23ac824 commit 93d07ad

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

Diff for: service_provider_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,72 @@ func addSignatureToDocument(doc *etree.Document) *etree.Document {
714714
return doc
715715
}
716716

717+
func removeDestinationFromDocument(doc *etree.Document) *etree.Document {
718+
responseEl := doc.FindElement("//Response")
719+
responseEl.RemoveAttr("Destination")
720+
return doc
721+
}
722+
723+
func TestServiceProviderMismatchedDestinationsWithSignaturePresent(t *testing.T) {
724+
test := NewServiceProviderTest()
725+
s := ServiceProvider{
726+
Key: test.Key,
727+
Certificate: test.Certificate,
728+
MetadataURL: mustParseURL("https://15661444.ngrok.io/saml2/metadata"),
729+
AcsURL: mustParseURL("https://15661444.ngrok.io/saml2/acs"),
730+
IDPMetadata: &EntityDescriptor{},
731+
}
732+
err := xml.Unmarshal([]byte(test.IDPMetadata), &s.IDPMetadata)
733+
assert.NoError(t, err)
734+
735+
req := http.Request{PostForm: url.Values{}}
736+
s.AcsURL = mustParseURL("https://wrong/saml2/acs")
737+
bytes, _ := addSignatureToDocument(test.responseDom()).WriteToBytes()
738+
req.PostForm.Set("SAMLResponse", base64.StdEncoding.EncodeToString(bytes))
739+
_, err = s.ParseResponse(&req, []string{"id-9e61753d64e928af5a7a341a97f420c9"})
740+
assert.EqualError(t, err.(*InvalidResponseError).PrivateErr,
741+
"`Destination` does not match AcsURL (expected \"https://wrong/saml2/acs\", actual \"https://15661444.ngrok.io/saml2/acs\")")
742+
}
743+
744+
func TestServiceProviderMissingDestinationWithSignaturePresent(t *testing.T) {
745+
test := NewServiceProviderTest()
746+
s := ServiceProvider{
747+
Key: test.Key,
748+
Certificate: test.Certificate,
749+
MetadataURL: mustParseURL("https://15661444.ngrok.io/saml2/metadata"),
750+
AcsURL: mustParseURL("https://15661444.ngrok.io/saml2/acs"),
751+
IDPMetadata: &EntityDescriptor{},
752+
}
753+
err := xml.Unmarshal([]byte(test.IDPMetadata), &s.IDPMetadata)
754+
assert.NoError(t, err)
755+
756+
req := http.Request{PostForm: url.Values{}}
757+
bytes, _ := removeDestinationFromDocument(addSignatureToDocument(test.responseDom())).WriteToBytes()
758+
req.PostForm.Set("SAMLResponse", base64.StdEncoding.EncodeToString(bytes))
759+
_, err = s.ParseResponse(&req, []string{"id-9e61753d64e928af5a7a341a97f420c9"})
760+
assert.EqualError(t, err.(*InvalidResponseError).PrivateErr,
761+
"`Destination` does not match AcsURL (expected \"https://15661444.ngrok.io/saml2/acs\", actual \"\")")
762+
}
763+
764+
func TestSPCanProcessResponseWithoutDestination(t *testing.T) {
765+
test := NewServiceProviderTest()
766+
s := ServiceProvider{
767+
Key: test.Key,
768+
Certificate: test.Certificate,
769+
MetadataURL: mustParseURL("https://15661444.ngrok.io/saml2/metadata"),
770+
AcsURL: mustParseURL("https://15661444.ngrok.io/saml2/acs"),
771+
IDPMetadata: &EntityDescriptor{},
772+
}
773+
err := xml.Unmarshal([]byte(test.IDPMetadata), &s.IDPMetadata)
774+
assert.NoError(t, err)
775+
776+
req := http.Request{PostForm: url.Values{}}
777+
test.replaceDestination("")
778+
req.PostForm.Set("SAMLResponse", base64.StdEncoding.EncodeToString([]byte(test.SamlResponse)))
779+
_, err = s.ParseResponse(&req, []string{"id-9e61753d64e928af5a7a341a97f420c9"})
780+
assert.NoError(t, err)
781+
}
782+
717783
func TestSPMismatchedDestinationsWithSignaturePresent(t *testing.T) {
718784
test := NewServiceProviderTest()
719785
s := ServiceProvider{

0 commit comments

Comments
 (0)