HIGH xml external entitieshapiapi keys

Xml External Entities in Hapi with Api Keys

Xml External Entities in Hapi with Api Keys — how this specific combination creates or exposes the vulnerability

An XML External Entity (XXE) vulnerability in a Hapi server can be triggered through an API endpoint that parses attacker-controlled XML input. When API keys are used for authorization, an attacker who does not possess a valid key can still exploit XXE if the endpoint accepts and parses XML without proper safeguards. The presence of API keys does not prevent XXE; it only controls access to the endpoint. If an API key is required but transmitted in a way that leaks to logs or error messages, XXE payloads may indirectly expose the key through out-of-band channels or error disclosures.

In Hapi, routes that use payload validation modes such as payload and rely on XML parsing libraries (for example, a custom XML parser or a plugin that deserializes XML) can be vulnerable if the parser is configured to load external entities. An attacker can send a crafted XML body with a malicious external entity reference, causing the parser to read local files, interact with internal services, or cause denial of service. Even when API keys are validated before business logic, a misconfigured parser may still process the XML before key validation completes, or an XXE may be chained with other issues to bypass controls. For example, an XXE can be used to read configuration files that contain hardcoded API keys or to probe internal endpoints that trust the API key header.

Consider a Hapi route that accepts XML and parses it with an unsafe parser:

const Hapi = require('@hapi/hapi');
const parseString = require('xml2js').parseString;

const server = Hapi.server({ port: 4000 });

server.route({
  method: 'POST',
  path: '/import',
  options: {
    payload: {
      parse: true,
      output: 'data',
      allow: 'application/xml'
    },
    validate: {
      payload: {
        // Example schema-like validation in Hapi (joi-based)
        // Note: this does not sanitize XML external entity references
      }
    }
  },
  handler: (request, h) => {
    const xmlBody = request.payload.data.toString();
    parseString(xmlBody, (err, result) => {
      if (err) { return h.response('Invalid XML').code(400); }
      // Process result
      return h.response('OK');
    });
  }
});

If the underlying xml2js parser is not configured to disable external entities, an attacker can submit:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>&xxe;</root>

This can lead to sensitive data exposure, including API keys stored in configuration files. Additionally, an XXE can be used to perform Server-Side Request Forgery (SSRF) against internal metadata services to discover further weaknesses. The API key itself does not mitigate XXE; it must be protected by secure parsing practices, input validation, and runtime controls.

To map findings, middleBrick scans 12 checks in parallel, including Input Validation and Data Exposure, and can detect unsafe XML parsing patterns and potential XXE in the unauthenticated attack surface. Findings include severity, reproduction steps, and remediation guidance without attempting to fix or block traffic.

Api Keys-Specific Remediation in Hapi — concrete code fixes

Remediation focuses on disabling external entity processing in XML parsers and ensuring API keys are handled securely. For Hapi, you should configure your XML parser to reject external entities and avoid passing raw XML to unsafe deserializers. If you do not need XML, disable XML parsing entirely.

Secure XML parsing example with external entity prevention using xml2js:

const Hapi = require('@hapi/hapi');
const parseString = require('xml2js').parseString;

const server = Hapi.server({ port: 4000 });

server.route({
  method: 'POST',
  path: '/import',
  options: {
    payload: {
      parse: true,
      output: 'data',
      allow: 'application/xml'
    }
  },
  handler: (request, h) => {
    const xmlBody = request.payload.data.toString();
    // Configure parser to disable external entities and avoid dangerous features
    parseString(xmlBody, {
      explicitArray: false,
      ignoreAttrs: false,
      // Ensure no external DTDs or entities are processed
      // xml2js does not support external entity disabling directly; consider using a secure parser or sanitize input
      mergeAttrs: false
    }, (err, result) => {
      if (err) { return h.response('Invalid XML').code(400); }
      // Process result
      return h.response('OK');
    });
  }
});

Better yet, use a dedicated secure XML parser that explicitly disables external entities. For Node.js, you can use libxmljs with safe options or an XML sanitizer. Example with a safer approach using xmldom and disabling external references:

const { DOMParser } = require('xmldom');
const Hapi = require('@hapi/hapi');

const server = Hapi.server({ port: 4000 });

server.route({
  method: 'POST',
  path: '/import',
  options: {
    payload: {
      parse: true,
      output: 'data',
      allow: 'application/xml'
    }
  },
  handler: (request, h) => {
    const xmlBody = request.payload.data.toString();
    try {
      // Configure DOMParser to avoid external entities
      const doc = new DOMParser({}).parseFromString(xmlBody, 'text/xml');
      // Validate and process doc safely
      return h.response('OK');
    } catch (err) {
      return h.response('Invalid XML').code(400);
    }
  }
});

API key handling should remain separate from XML parsing. Always validate the API key early in the request lifecycle, using Hapi’s auth strategies, and avoid echoing keys in responses or logs. Combine these measures with rate limiting and monitoring to reduce risk. middleBrick’s Pro plan enables continuous monitoring and CI/CD integration to detect regressions, including checks mapped to frameworks like OWASP API Top 10 and compliance requirements.

When you need guided scanning and prioritization, the Dashboard allows you to track scores over time, while the CLI supports scripting and automation. The GitHub Action can enforce score thresholds in pipelines, and the MCP Server integrates scanning into AI coding assistants. These tools report findings and remediation guidance but do not alter or block traffic.

Frequently Asked Questions

Does using API keys prevent XML External Entity attacks in Hapi?
No. API keys control access to endpoints but do not prevent XXE if the application parses XML unsafely. XXE is about how XML is processed, not about authentication. Disable external entities in your XML parser and validate/sanitize input regardless of authentication or authorization mechanisms.
Can an XXE expose API keys even if keys are validated first?
Yes. If an endpoint parses XML before key validation, or if XXE is chained with other flaws (e.g., SSRF), attackers may read files or probe internal services that reveal keys. Additionally, keys may leak via error messages or logs. Secure parsing and defense-in-depth are required.