XML External Entity (XXE) via libxml in Express

High Risk XML External Entity
javascriptexpressxxexmllibxmlexternal-entities

What it is

XXE vulnerabilities occur when Express applications use libxml or libxmljs to parse XML without disabling external entity processing. Attackers can craft malicious XML payloads containing external entity references that read local files, perform SSRF attacks, or cause denial of service through entity expansion.

const express = require('express');
const libxmljs = require('libxmljs');

const app = express();

// VULNERABLE: default settings allow external entities
app.post('/parse-xml', (req, res) => {
    const xmlData = req.body;
    
    // DANGEROUS: noent defaults to true, allowing entity expansion
    const doc = libxmljs.parseXml(xmlData);
    
    const result = doc.get('//data').text();
    res.json({ result });
});

// Attack payload:
// <?xml version="1.0"?>
// <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
// <root><data>&xxe;</data></root>
const express = require('express');
const libxmljs = require('libxmljs');

const app = express();

// SECURE: disable external entities
app.post('/parse-xml', (req, res) => {
    const xmlData = req.body;
    
    // SAFE: noent: false disables entity substitution
    const doc = libxmljs.parseXml(xmlData, {
        noent: false,  // Disable entity substitution
        nonet: true    // Disable network access
    });
    
    const result = doc.get('//data').text();
    res.json({ result });
});

💡 Why This Fix Works

The vulnerable code uses libxml with default settings that allow external entity expansion, enabling XXE attacks. The secure version explicitly disables entity substitution with noent: false and network access with nonet: true, preventing XXE exploitation.

Why it happens

Using libxml with default settings that allow external entity processing.

Root causes

Default libxml Configuration

Using libxml with default settings that allow external entity processing.

Not Setting noent Option

Failing to set noent: false to disable entity substitution.

Processing Untrusted XML

Parsing XML from user uploads or external sources without security configuration.

Fixes

1

Disable External Entities

Set noent: false and nonet: true when creating libxml parser.

2

Use Safe XML Parsers

Consider using xml2js or fast-xml-parser with safe defaults instead of libxml.

3

Validate XML Structure

Validate XML against expected schema before parsing.

Detect This Vulnerability in Your Code

Sourcery automatically identifies xml external entity (xxe) via libxml in express and many other security issues in your codebase.