Xml External Entities in Hapi
How Xml External Entities Manifests in Hapi
Xml External Entities (XXE) attacks exploit XML parsers that process external entity references, allowing attackers to read arbitrary files, perform SSRF, or cause denial of service. In Hapi applications, XXE vulnerabilities typically manifest through XML parsing endpoints, file upload handlers, and configuration systems that process XML.
The most common attack vector in Hapi is through request bodies that accept XML content. When a Hapi route handler uses Node.js's built-in xml2js or similar XML parsing libraries without proper configuration, it creates an attack surface. Consider this vulnerable Hapi route:
const Hapi = require('@hapi/hapi');
const xml2js = require('xml2js');
const init = async () => {
const server = Hapi.server({ port: 3000 });
server.route({
method: 'POST',
path: '/upload-xml',
handler: async (request, h) => {
const parser = new xml2js.Parser();
const xmlData = request.payload.xml;
// Vulnerable: no entity expansion limits or external entity blocking
return parser.parseStringPromise(xmlData);
}
});
await server.start();
};
init();This code allows an attacker to send a malicious XML payload like:
]>
&xxe; The parser would read the /etc/passwd file and return its contents in the response, exposing sensitive system information.
Another Hapi-specific manifestation occurs in configuration-driven applications. Many Hapi plugins and extensions use XML for configuration files. If these configurations are processed without validation, attackers can exploit XXE through configuration injection. For example, a plugin that reads XML configuration from environment variables or database-stored configurations could be vulnerable.
XXE can also manifest through Hapi's file upload system when processing XML files. The h.file() handler or multipart processing can inadvertently parse XML metadata if not properly configured. Attackers might upload XML files with malicious external entity declarations that get processed during file handling or metadata extraction.
Denial of service through entity expansion is another critical manifestation. Attackers can craft XML with deeply nested or exponentially expanding entities that consume excessive memory or CPU. A Hapi endpoint processing such XML could become unresponsive, leading to availability issues. This is particularly dangerous in serverless environments where resource consumption directly impacts costs.
Hapi-Specific Detection
Detecting XXE vulnerabilities in Hapi applications requires both static analysis and dynamic scanning. Static analysis involves reviewing XML parsing code paths and configuration files. Look for these patterns in your Hapi codebase:
# Search for vulnerable XML parsing patterns
grep -r "xml2js\|xmlParser\|DOMParser" routes/ plugins/ --include="*.js"
grep -r "DOCTYPE\|ENTITY" routes/ plugins/ --include="*.js"
Dynamic detection with middleBrick provides comprehensive runtime analysis. middleBrick's black-box scanning tests Hapi endpoints for XXE vulnerabilities by sending crafted XML payloads to all POST endpoints that might accept XML content. The scanner automatically:
- Identifies XML-accepting endpoints through content-type analysis
- Sends XXE test payloads with various entity declarations
- Monitors responses for signs of successful entity expansion
- Checks for file disclosure through path traversal attempts
- Tests for denial of service through entity expansion limits
middleBrick's scanning process for Hapi applications includes these specific XXE checks:
# Scan your Hapi API with middleBrick
npm install -g middlebrick
middlebrick scan https://yourapi.com --category xml-external-entities
The scanner tests 27 different XXE patterns, including:
- Basic file disclosure (
file://URIs) - SSRF through network protocols (
http://,ftp://) - PHP filter wrappers (
php://filter) - Relative path traversal (
file://../) - Windows UNC paths (
file:////server/share/)
middleBrick also analyzes OpenAPI specifications for Hapi applications, identifying endpoints that accept XML content types and prioritizing them for XXE testing. The scanner provides severity ratings based on the potential impact and likelihood of exploitation.
For CI/CD integration, the middleBrick GitHub Action can automatically scan Hapi APIs before deployment:
- name: Run middleBrick Security Scan
uses: middlebrick/middlebrick-action@v1
with:
api-url: "http://localhost:3000"
fail-on-severity: "high"
categories: "xml-external-entities,authentication,bolsa"
This ensures XXE vulnerabilities are caught early in the development lifecycle, preventing them from reaching production environments.
Hapi-Specific Remediation
Remediating XXE vulnerabilities in Hapi requires a defense-in-depth approach. The primary defense is configuring XML parsers to disable external entity processing and entity expansion. For applications using xml2js, implement these security measures:
const Hapi = require('@hapi/hapi');
const xml2js = require('xml2js');
const init = async () => {
const server = Hapi.server({ port: 3000 });
// Secure XML parser configuration
const secureParser = new xml2js.Parser({
// Disable external entities
strict: true,
// Limit entity expansion to prevent DoS
strictEntities: true,
// Set maximum depth to prevent exponential expansion
maxDepth: 100,
// Limit attribute count
maxAttrs: 100,
// Disable external entity loading
ignoreAttrs: true,
// Validate against a schema if possible
validator: (xml) => {
// Custom validation logic
if (xml.includes(' {
try {
const xmlData = request.payload.xml;
const result = await secureParser.parseStringPromise(xmlData);
return result;
} catch (error) {
return h.response({ error: 'Invalid XML content' }).code(400);
}
}
});
await server.start();
};
init();For applications using the built-in DOMParser (common in browser-based Hapi applications), configure it securely:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({ port: 3000 });
server.route({
method: 'POST',
path: '/process-xml',
handler: (request, h) => {
const xmlString = request.payload.xml;
// Create a secure XML parser
const parser = new DOMParser({
// Disable external entity loading
// Note: DOMParser options vary by environment
});
try {
// Parse with error handling
const xmlDoc = parser.parseFromString(xmlString, 'application/xml');
// Check for parsing errors
const parserErrors = xmlDoc.getElementsByTagName('parsererror');
if (parserErrors.length > 0) {
throw new Error('XML parsing error detected');
}
return xmlDoc;
} catch (error) {
return h.response({ error: 'XML processing failed' }).code(400);
}
}
});
await server.start();
};
init();For Hapi applications using middleware or plugins that process XML, ensure they're configured securely. Many third-party Hapi plugins for XML processing have XXE vulnerabilities in their default configurations. Always review plugin documentation for security recommendations.
Input validation provides an additional layer of defense. Before processing XML content, validate that it conforms to expected schemas and doesn't contain suspicious patterns:
const Hapi = require('@hapi/hapi');
const xml2js = require('xml2js');
function validateXmlContent(xmlString) {
// Check for external entity declarations
if (xmlString.includes(' xmlString.includes(proto))) {
throw new Error('Suspicious protocol detected');
}
return true;
}
const init = async () => {
const server = Hapi.server({ port: 3000 });
server.route({
method: 'POST',
path: '/secure-xml',
handler: async (request, h) => {
try {
const xmlData = request.payload.xml;
// Validate before parsing
validateXmlContent(xmlData);
const parser = new xml2js.Parser({
strict: true,
maxDepth: 50
});
const result = await parser.parseStringPromise(xmlData);
return result;
} catch (error) {
return h.response({ error: error.message }).code(400);
}
}
});
await server.start();
};
init();For applications that must process XML but need to mitigate XXE risk, consider using XML sanitizers or converting XML to JSON before processing. Libraries like libxmljs with proper configuration or cloud-based XML processing services can provide additional security layers.
Finally, implement proper logging and monitoring for XML processing failures. Unusual patterns in XML parsing errors or repeated requests with malformed XML can indicate attack attempts. Integrate these logs with your security monitoring systems to detect and respond to potential XXE attacks in real-time.