XML External Entity (XXE) via libxml in VM Sandbox

High Risk XML External Entity
javascriptexpressxxexmllibxmlvm2sandbox

What it is

XXE vulnerabilities occur when XML parsing with libxml inside VM2 or similar sandboxes fails to disable external entity processing. Even within sandboxed environments, XXE can read local files, perform SSRF attacks, or cause denial of service through billion laughs attacks, potentially escaping sandbox protections.

const express = require('express');
const {VM} = require('vm2');
const libxmljs = require('libxmljs');

const app = express();

// VULNERABLE: libxml in VM without proper configuration
app.post('/parse-xml', (req, res) => {
    const xmlData = req.body;
    
    const vm = new VM();
    const parseCode = `
        const libxml = require('libxmljs');
        // DANGEROUS: default settings allow XXE even in VM
        const doc = libxml.parseXml(xmlData);
        doc.get('//data').text();
    `;
    
    const result = vm.run(parseCode);
    res.json({ result });
});

// Attack: XXE payload still works inside VM
// <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
// <root><data>&xxe;</data></root>
const express = require('express');
const {VM} = require('vm2');
const libxmljs = require('libxmljs');

const app = express();

// SECURE: disable entities even in VM
app.post('/parse-xml', (req, res) => {
    const xmlData = req.body;
    
    const vm = new VM();
    const parseCode = `
        const libxml = require('libxmljs');
        // SAFE: noent: false prevents XXE in VM
        const doc = libxml.parseXml(xmlData, {
            noent: false,  // Disable entity substitution
            nonet: true    // Disable network access
        });
        doc.get('//data').text();
    `;
    
    const result = vm.run(parseCode);
    res.json({ result });
});

💡 Why This Fix Works

The vulnerable code uses libxml inside a VM sandbox with default settings that allow XXE attacks. Sandboxes don't automatically prevent XXE. The secure version explicitly disables entity substitution with noent: false even within the sandboxed environment.

Why it happens

Using libxml with default settings inside VM2 or other sandboxes.

Root causes

Default libxml Configuration in Sandbox

Using libxml with default settings inside VM2 or other sandboxes.

Not Setting noent in Sandboxed Code

Failing to set noent: false in XML parsing configuration within sandboxed execution.

Trusting Sandbox for XML Security

Assuming sandbox prevents XXE without explicit XML parser configuration.

Fixes

1

Disable Entities in Sandbox

Set noent: false and nonet: true even within sandboxed environments.

2

Use Safe XML Parsers

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

3

Validate Before Sandboxing

Validate and sanitize XML before passing to sandboxed code.

Detect This Vulnerability in Your Code

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