Sharing my knowledge on security topic.

View on GitHub
2 November 2021

SAML 101

by Devang-Solanki

Before diving deep into SAML we must understand Single Sign-On is.

What Is Single Sign-On

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.

What is SAML

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.

Example :- Suppose you want to use Gmail, Hangouts and Google Docs we can call them service provider. Sigining into all of them separately and remmebering passwords for all of them seems very annoying. So, to solve this problem we will use SAML. Where we will only provide credentials to one Identity Provider in this case it would be Google and that IDP will allow us to login into Gmail, Hangouts and Google Docs without providing any credentials to them.

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.

Basic SAML Terminology

SAML Authentication Workflow


At a basic level, a successful Service Provider Initiated SAML flow occurs as follows:

  1. The user (e.g. navigates to the SP’s login page and begins to log in. Some SPs offer a link to “sign in using SSO” on the login page (e.g. hackerone). The service provider checks to see if you’re already authenticated within the system. If you are, you skip to step 7; if you’re not, the service provider starts the authentication process.
  2. The SP then generates a SAML request and redirects the user to the appropriate IDP.
  3. Once the user is redirected to IDP they’ll need to enter their credentials, unless they had already authenticated into IDP in a previous session within the same browser.
  4. On successful authentication request IDP will redirect the user back to the SP’s Assertion Consumer Service (ACS) with an SAML response from IDP containing the authentication information needed by the service provider.
  5. After the response is successfully processed by the SP, the user will logs you in. After this user will be redirected to SP’s default relay state.

SAML Request

An AuthnRequest is sent by the Service Provider to the Identity Provider in the SP-initiated flow.

<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="" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="">
  <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
  <samlp:RequestedAuthnContext Comparison="exact">

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="" that points to IDP and also helps ensure IDP that its the intended recipient of SAML request. The ACS AssertionConsumerServiceURL="" tells the IDP that where the SP accept the SAML response.

SAML Response

A SAML Response is generated by the Identity Provider. It contains the actual assertion of the authenticated user.

<?xml version="1.0"?>
<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="" InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24">
  <saml:Issuer></saml:Issuer><ds:Signature xmlns:ds="">
  <ds:SignedInfo><ds:CanonicalizationMethod Algorithm=""/>
    <ds:SignatureMethod Algorithm=""/>
  <ds:Reference URI="#pfx3572f7e6-48ee-b750-7939-5475435beb62"><ds:Transforms><ds:Transform Algorithm=""/><ds:Transform Algorithm=""/></ds:Transforms><ds:DigestMethod Algorithm=""/><ds:DigestValue>F0yFi+7QJVS4HaAFEk5WSOxnyUQ=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>OrwZ2o/uROEvTujoyRnV58Q6Q4NtUoYOsB0zPh09QrJkMGcXREQG+1GvT+YDDCdgyq6Z895QyVm9fS0rKv19eUd8Uh+Nbsx3VirsSAvVR77vyOmCZrpdNFE4A2xRG7jcIl/2JDeN9dFNuh1nNdyX1e7qJIaWutL3o/LJIx8SR2o=</ds:SignatureValue>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  <saml:Assertion xmlns:xsi="" xmlns:xs="" ID="pfx19d38796-12f1-c9b0-edd4-73c3f560f99a" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
    <saml:Issuer></saml:Issuer><ds:Signature xmlns:ds="">
  <ds:SignedInfo><ds:CanonicalizationMethod Algorithm=""/>
    <ds:SignatureMethod Algorithm=""/>
  <ds:Reference URI="#pfx19d38796-12f1-c9b0-edd4-73c3f560f99a"><ds:Transforms><ds:Transform Algorithm=""/><ds:Transform Algorithm=""/></ds:Transforms><ds:DigestMethod Algorithm=""/><ds:DigestValue>W6keCv1rK7ZsH68VuoSrfF1Abvo=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>pmf6u8mZyxKlDOe1Idf8MGF/w4Ky2NC1Q16fISLjvb+t1+lnX7g4L9B/v0xnJ2Mskyuyr2yWCf6MBzYGgeu0fS4iRtX7LjOTgYVOjUdEbHWZrYt69c/Kyl/RM/B4/Po5bi6HmXM4pbTWCxwZYhhO/Szhsa1N7zIlqp0eG3fuucw=</ds:SignatureValue>
      <saml:NameID SPNameQualifier="" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"></saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="" InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24"/>
    <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
    <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
      <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
      <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string"></saml:AttributeValue>
      <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
        <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>

Notice in SAML response we have Destination=" and InResponseTo="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24" which matches to ID="ONELOGIN_809707f0030a5d00620c9d9df97f627afe9dcc24" and AssertionConsumerServiceURL="" 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=""/> 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="" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"></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

Weak Points

SAML might be complex, but it can be secure if properly impelmented. Lets look at some mistake that could lead to disaster.

Flawed Validation

Message Expiration

SAML messages should contain a timestamp of when the request was issued, when it expires or both. If the SAML message never expires a malicious user could capture the SAML response and reuse it. Check the message for timestamps, such as an IssueInstant or NotOnOrAfter assertion.

SAML Response Forwarding

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 another application which uses the same IP and login to the that SP application.

Flawed Signature Validation Mechanisim

The SAML authentication mechanism relies on signature for maintaing its intergrity and if they are not properly implemented this can leads to authentication bypass or account takeover.

Signature is not verified

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.

Signature is only verified if it exist

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.

Flawed XML Parsers

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 Comment Injection

XML can be quite complicated. Diffrent XML parsers parses XML diffrently. For example take this two xml tag mentioned below

<email><!-- Here lies the problem --></email> 

Seems diffrent right?

Let’s see what we get when we parsed both the xml and gets it element tree

First Case:

element: email
|_ text:

Second Case:

|_ Text:
|_ Comment: Here lies the problem
|_ Text:

In second case the comment tricked the XML parser into stoping at that comment and the service provider would thought the user was just beacuse it failed to notice

A malicious user could leverage this problem and can create a account very similar to a admin account like and can modify SAML assertions to change the NameID to when processed by the SP. By adding simple comment into the SAML response malicous user can now access admin account with this simple payload

    <Assertion ID="_id1234">
            <CanonicalizationMethod Algorithm="xml-c14n11"/>
            <Reference URI="#_id1234"/>
            some base64 data that represents the signature of the assertion

XML Signature Wrapping Attack

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.

Best Practices