Before diving deep into SAML we must understand Single Sign-On is.
Single sign-on is a method of logging in that lets a user enter in their login credentials (usually a username and password) just once and automatically be logged into multiple websites or applications.
SAML stands for Security Assertion Markup Language. It is a standard commonly used Single Sign-On (SSO). It is an XML-based open-standard for transferring identity data or authorization credentials between two parties: an identity provider (IdP) and a service provider (SP).
Identity Provider (IDP) — Performs authentication and passes the user's identity and authorization level to the service provider.
Service Provider (SP) — Trusts the identity provider and authorizes the given user to access the requested resource.
SAML implements a secure method of passing user authentications and authorizations between the identity provider and service providers. When a user logs into a SAML enabled application, the service provider requests authorization from the appropriate identity provider. The identity provider authenticates the user’s credentials and then returns the authorization for the user to the service provider, and the user is now able to use the application.
SAML messages are base64 encoded but that is easily decoded to view the message contents. The two most common areas in SAML messages that are prone to tampering are signatures and assertions. The signature enforces the trust relationship between the IP and SP. The assertion instructs the SP on what trusted operations to perform, usually to allow you to access the application as a certain user.
At a basic level, a successful Service Provider Initiated SAML flow occurs as follows:
An AuthnRequest is sent by the Service Provider to the Identity Provider in the SP-initiated flow.
1<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24" Version="2.0" ProviderName="SP test" IssueInstant="2014-07-16T23:52:45Z" Destination="http://idp.example.com/SSOService.php" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs"> 2 <saml:Issuer>http://sp.example.com/demo1/metadata.php</saml:Issuer> 3 <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/> 4 <samlp:RequestedAuthnContext Comparison="exact"> 5 <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> 6 </samlp:RequestedAuthnContext> 7</samlp:AuthnRequest> 8
In SAML request the ID ID="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"
is generated by SP and the IDP will respond to this ID within it's SAML response. SAML request contains Destination value Destination="http://idp.example.com/SSOService.php"
that points to IDP and also helps ensure IDP that its the intended recipient of SAML request. The ACS AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs"
tells the IDP that where the SP accept the SAML response.
A SAML Response is generated by the Identity Provider. It contains the actual assertion of the authenticated user.
1<?xml version="1.0"?> 2<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="pfx3572f7e6-48ee-b750-7939-5475435beb62" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"> 3 <saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 4 <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 5 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 6 <ds:Reference URI="#pfx3572f7e6-48ee-b750-7939-5475435beb62"><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>F0yFi+7QJVS4HaAFEk5WSOxnyUQ=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>OrwZ2o/uROEvTujoyRnV58Q6Q4NtUoYOsB0zPh09QrJkMGcXREQG+1GvT+YDDCdgyq6Z895QyVm9fS0rKv19eUd8Uh+Nbsx3VirsSAvVR77vyOmCZrpdNFE4A2xRG7jcIl/2JDeN9dFNuh1nNdyX1e7qJIaWutL3o/LJIx8SR2o=</ds:SignatureValue> 7<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature> 8 <samlp:Status> 9 <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> 10 </samlp:Status> 11 <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfx19d38796-12f1-c9b0-edd4-73c3f560f99a" Version="2.0" IssueInstant="2014-07-17T01:01:48Z"> 12 <saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 13 <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 14 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 15 <ds:Reference URI="#pfx19d38796-12f1-c9b0-edd4-73c3f560f99a"><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>W6keCv1rK7ZsH68VuoSrfF1Abvo=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>pmf6u8mZyxKlDOe1Idf8MGF/w4Ky2NC1Q16fISLjvb+t1+lnX7g4L9B/v0xnJ2Mskyuyr2yWCf6MBzYGgeu0fS4iRtX7LjOTgYVOjUdEbHWZrYt69c/Kyl/RM/B4/Po5bi6HmXM4pbTWCxwZYhhO/Szhsa1N7zIlqp0eG3fuucw=</ds:SignatureValue> 16<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature> 17 <saml:Subject> 18 <saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">[email protected]</saml:NameID> 19 <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> 20 <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"/> 21 </saml:SubjectConfirmation> 22 </saml:Subject> 23 <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z"> 24 <saml:AudienceRestriction> 25 <saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience> 26 </saml:AudienceRestriction> 27 </saml:Conditions> 28 <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93"> 29 <saml:AuthnContext> 30 <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef> 31 </saml:AuthnContext> 32 </saml:AuthnStatement> 33 <saml:AttributeStatement> 34 <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> 35 <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue> 36 </saml:Attribute> 37 <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> 38 <saml:AttributeValue xsi:type="xs:string">[email protected]</saml:AttributeValue> 39 </saml:Attribute> 40 <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> 41 <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue> 42 <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue> 43 </saml:Attribute> 44 </saml:AttributeStatement> 45 </saml:Assertion> 46</samlp:Response> 47
Notice in SAML response we have Destination="http://sp.example.com/demo1/index.php?acs
and InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"
which matches to ID="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"
and AssertionConsumerServiceURL="http://sp.example.com/demo1/index.php?acs"
this helps us verify that this SAML response is generated in response to the SAML request we made. We have multiple assertion within the SAML respone which are all signed using some alogrithim which we can identify using <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
this tag. The <ds:KeyInfo>
tag has public key which the IDP used to sign asserstion to protect its integrity. The signed asserstion is then Base64 encoded and stored into the <ds:DigestValue>
tag.
In this SAML response we have a subject <saml:Subject>
this is in refernece to user sigining in to SP. The subject contains a nameID <saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">[email protected]</saml:NameID>
which helps to uniquely indentify the user.
At last we have the conditions <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
which give us timestamps that this response is valid in the time frame window from NotBefore="2014-07-17T01:01:18Z"
to NotOnOrAfter="2024-01-18T06:21:48Z
SAML messages should contain a timestamp of when the request was issued, when it expires or both. If the SAML message never expires or if the expiratioMessage Expiration: SAML messages should contain a timestamp of when the request was issued, when it expires or both. If the SAML message never expires or if the expiration is not honored, there is a greater risk of a message falling into the hands of an attacker. Check the message for timestamps, such as an IssueInstant or NotOnOrAfter assertion.n is not honored, there is a greater risk of a message falling into the hands of an attacker. Check the message for timestamps, such as an IssueInstant or NotOnOrAfter assertion.
An application should only accept a SAML response intended for the SP application. If the application does not perform this check, malicous user could pass a valid SAML response genrated for an application to another application and allow it to login. The malicous user can get a valid login for application and record it then the user can replay the same message to anothe application which uses the same IP, login to the that SP application.
The SAML authentication mechanism relies on signature for maintaing its intergrity and if they are not properly implemented this can leads to bypass authentication and account takeover. SAML might be complex, but it can be secure if properly impelmented.
If the ACS is not verifying the signature or not checking if its exist in SAML response a malicous user could try removing the signature value from the SAML response. By simply emptying the signature field or removing the field entirely malicious user can bypass security checks.
Sometimes service provider only verify the signature if it is present in the SAML response. If it's not being provided, in that case ACS simply skips the validation.
The service provider processes the SAML response which is basicaly a XML document hence vulnerbilty exist in XML also exist in SAML such as XXE.
XML can be quite complicated. Diffrent XML parsers parses XML diffrently. For example take this two xml tag mentioned below
1<email>[email protected]</email> 2
1<email>[email protected]<!-- Here lies the problem --></email> 2
Seems diffrent right?
Let's see what we get when we parsed both the xml and gets it element tree
First Case:
1element: email 2|_ text: [email protected] 3
Second Case:
1NameID 2|_ Text: [email protected] 3|_ Comment: Here lies the problem 4|_ Text: .evil.com 5
In second case the comment tricked the xml parser into stoping at that comment and the service provider would thought the user was just [email protected] beacuse it failed to notice .evil.com.
A malicious user could leverage this problem and can create a account very similar to a admin account like [email protected] and can modify SAML assertions to change the NameID to [email protected] when processed by the SP. By adding simple comment into the SAML response malicous user can now access admin account with this simple payload
1<SAMLResponse> 2 <Issuer>https://idp.com/</Issuer> 3 <Assertion ID="_id1234"> 4 <Subject> 5 <NameID>[email protected]<!---->.evil.co/NameID> 6 </Subject> 7 </Assertion> 8 <Signature> 9 <SignedInfo> 10 <CanonicalizationMethod Algorithm="xml-c14n11"/> 11 <Reference URI="#_id1234"/> 12 </SignedInfo> 13 <SignatureValue> 14 some base64 data that represents the signature of the assertion 15 </SignatureValue> 16 </Signature> 17</SAMLResponse> 18
Some implementations check for a valid signature and match it to a valid assertion, but do not check for multiple assertions, multiple signatures, or behave differently depending on the order of assertions. A malicous user can malformed a SAML message which contains one signed asseertion and a second unsigned assertion formed by user. When this SAML message is forwarded to Assertion Consumer Service depending on XML Parser it will validate the signed assertion but will process the unsigned malicious assertion.
This could also allow a malicous user to bloat a XML document and ddos Assertion Consumer Service.
SAML 101