On SAP Security Patch Day, June 9 2026, SAP shipped Security Note 3746332 for CVE-2026-44748, a CVSS 9.9 flaw in SAP NetWeaver Application Server ABAP that opens a full SAML authentication bypass. The root cause is filed as CWE-347, improper verification of a cryptographic signature, and the mechanism is a classic that keeps coming back: XML Signature Wrapping. An attacker takes a genuine, correctly signed login assertion and rearranges the document so the server checks the signature over one part while reading the user’s identity from another. There was no confirmed exploitation in the wild at disclosure, but the pattern is worth understanding because it defeats a signature check without ever breaking the signature.
What a SAML assertion actually promises
SAML is how one system tells another “I already logged this person in, and they are who they say.” The system that checks credentials is the Identity Provider (IdP). The system that grants access is the Service Provider (SP). When you sign in to a company dashboard through single sign on, the IdP builds an XML document called an assertion that says, in effect, this subject is alice@acme.com, valid until this time, for this audience. The IdP signs that XML with its private key. The SP holds the IdP’s public key and verifies the signature. If it checks out, the SP trusts the identity inside and creates a session.
The whole model rests on one belief: if the signature is valid, then the identity the SP reads is the identity the IdP vouched for. That link between what was signed and what is read is the only thing standing between a visitor and any account. If you have not thought about how signing and reading can drift apart, our note on authentication vs authorization is a useful warm up, because this bug lives entirely on the authentication side.
How the signature points at what it covers
An XML Signature does not sign the whole document by default. It signs specific elements, named by an ID, through a <Reference URI="#..."> inside the <Signature> block. The verifier follows that reference, canonicalizes the target element, and checks the digest. So the signature says “I cover the element with this ID.” Nothing forces the rest of the code to then read identity from that same element. That gap is where the trouble starts.
The XML Signature Wrapping move behind the SAML authentication bypass
Picture a made up IdP and SP pair, “Acme SSO.” A legitimate assertion for a low privilege user might look like this, trimmed for clarity:
<Response>
<Assertion ID="A">
<Subject><NameID>guest@acme.com</NameID></Subject>
</Assertion>
<Signature>
<Reference URI="#A"/> <!-- signs the element with ID "A" -->
...
</Signature>
</Response>
An attacker who can capture any one valid assertion, even their own low privilege login, now has a signature they cannot forge but can move. They keep the signed Assertion ID="A" intact so the signature still validates, then they inject a second, unsigned assertion carrying the identity they want:
<Response>
<Assertion ID="EVIL">
<Subject><NameID>admin@acme.com</NameID></Subject>
</Assertion>
<Assertion ID="A">
<Subject><NameID>guest@acme.com</NameID></Subject>
<Signature>
<Reference URI="#A"/> <!-- still valid over "A" -->
...
</Signature>
</Assertion>
</Response>
Now two things happen in the SP, and they look at different elements. The signature layer walks the Reference URI="#A", finds the original signed assertion, canonicalizes it, and the digest matches. Signature valid. A separate piece of code then asks “which assertion do I use for identity?” and, because of how it queries the parsed tree, grabs the first Assertion it finds, or the one nearest the document root, which is now ID="EVIL". It reads admin@acme.com. The signature was real, the identity was not, and nothing in the flow noticed that the verified element and the consumed element were two different things.
The attacker never breaks the signature. They break the assumption that the signed element and the element the server actually reads are the same one.
The variations are all the same idea: move the signed element into a wrapper, bury it, or reference it by an ID that the identity reader resolves differently than the signature verifier does. XML is flexible about structure and ID resolution, and that flexibility is exactly what lets the two lookups disagree. If you want the deeper protocol walk through, we cover the variants in SAML signature wrapping.
How to spot it
You are looking for any place where signature verification and identity extraction are decoupled. A few concrete checks:
- Count the assertions. A well formed response has one assertion in play. If a parsed message contains more than one
Assertion, or more than oneSubject, treat it as hostile rather than picking a winner. - Compare the two elements by identity, not by value. After verification, confirm that the exact node whose signature you checked is the same node object you then read
NameIDfrom. Not an element with the same ID, the same one. - Watch for reference by string search. Code that finds the assertion with
getElementsByTagName("Assertion")[0]or an XPath that returns the first match is reading position, not the signed target. That is the classic wrapping foothold. - Log signed IDs against consumed IDs. In real time, record which
IDthe signature covered and which element supplied the identity. If they ever differ, you have either a bug or an attack.
How to prevent it
The fix is to force the signed element and the consumed element to be one and the same, and to remove the ambiguity that lets a document contain a decoy.
- Validate that the signature covers the exact element you consume. Extract identity only from the node that verification returned as signed. Never re query the document for “an assertion” afterward.
- Use schema aware and position aware validation. Validate the message against a strict schema before trust decisions, and reject any structure that adds elements the schema does not expect or places them where they do not belong.
- Reference by a canonicalized ID and pin resolution. Make sure the ID the signature resolves and the ID the identity reader resolves use the same rules, so an injected
ID="EVIL"cannot win a second lookup. - Reject assertions whose signed element is not the one used. If the message carries more than one assertion, or the signed element is not the top level assertion you act on, fail closed.
- Prefer a well tested SAML library and mark the IdP public keys. Pin the exact keys you accept, and lean on libraries that have already been hardened against wrapping rather than hand rolling XML verification.
CVE-2026-44748 is a reminder that “the signature is valid” is not the same claim as “this identity is the one that was signed.” Improper verification of a cryptographic signature, CWE-347, is rarely a broken crypto primitive. It is almost always this drift between what was checked and what was trusted, and it hides in the seam between two functions that each look correct alone. This is exactly the kind of assumption an autonomous researcher that tests how an application actually reads a request, and proves the finding with evidence, is built to surface. More on that approach on our about page.
Frequently asked questions
What is a SAML authentication bypass?
It is an attack where a valid signed SAML assertion is rearranged so the service provider checks the signature over one element but reads the user’s identity from a different, attacker added element. The signature is real, the identity is forged.
What is XML Signature Wrapping?
It is the technique behind the bypass. The attacker keeps a genuinely signed element intact so the signature still validates, then injects a second unsigned assertion in the spot where the identity reader looks first.
Does it break the cryptographic signature?
No. The signature stays valid over the original element. The flaw is that the verified element and the consumed element are not the same one, so a real signature ends up vouching for an identity it never covered.
How do you prevent it?
Read identity only from the exact node the signature verified, reject any message that carries more than one assertion, validate against a strict schema before trusting structure, and use a well tested SAML library instead of hand rolled XML checks.
Put an autonomous researcher on your own systems
UnboundCompute is an autonomous security researcher that reasons about how an application fits together and proves the access control and injection bugs it finds. We are opening a small number of founding design partner seats: private early access pointed at a staging target you choose, and a say in what it looks for. If your team ships software worth pressure testing, apply to the design partner program.
