HIGH xml external entitiesadonisjsmongodb

Xml External Entities in Adonisjs with Mongodb

Xml External Entities in Adonisjs with Mongodb — how this specific combination creates or exposes the vulnerability

XML External Entity (XXE) injection occurs when an application processes XML input and allows an external entity to be defined, leading to disclosure of local files, SSRF, or denial of service. In AdonisJS, this risk arises when an XML parser is used to process untrusted XML data and the parsed data is later stored in or retrieved from MongoDB. Although AdonisJS does not enable XML parsing by default, developers who add XML parsers (e.g., xml2js or fast-xml-parser) and then persist parsed documents into a MongoDB collection may inadvertently introduce XXE vectors. If entity expansion is not disabled, an attacker-supplied XML payload can reference local files or internal network resources; the resulting data written to MongoDB may contain sensitive content or trigger SSRF when later used by other services.

The exposure is compounded when AdonisJS applications expose endpoints that accept XML and store results in MongoDB without schema validation or input sanitization. For example, an endpoint that imports configuration or document data via XML and inserts the parsed JavaScript object into a MongoDB collection can propagate malicious entity references into stored data. If downstream consumers read that data and render it as XML or pass it to other internal endpoints, the malicious entity can be triggered again, leading to data exfiltration or internal network probing. This chain—untrusted XML parsing, MongoDB persistence, and unsafe consumption—illustrates how XXE can manifest in an AdonisJS + MongoDB stack even though the database itself does not process XML.

Additionally, if your application uses AdonisJS with a MongoDB driver that supports GridFS for storing large files, and those files are XML documents, failing to disable external entity processing during parsing can lead to similar injection issues. Attackers may attempt to embed DOCTYPE declarations with entity definitions in uploaded XML files; when the file is parsed and stored, the entities can be expanded, reading files such as /etc/passwd or triggering SSRF via file:// or http:// references. Because the stored data may later be exported or used in reports, the risk persists beyond the initial ingest.

Mongodb-Specific Remediation in Adonisjs — concrete code fixes

To mitigate XXE in an AdonisJS application that uses MongoDB, focus on preventing external entity expansion during XML parsing and ensuring that data stored in MongoDB is validated and sanitized. Below are concrete code examples using the official MongoDB Node.js driver in an AdonisJS controller.

Disable external entities when parsing XML

Choose a parser and configure it to prohibit external entities. For xml2js, disable DTD processing and entity parsing:

const xml2js = require('xml2js');

const parser = new xml2js.Parser({
  explicitArray: false,
  ignoreAttrs: false,
  mergeAttrs: true,
  // xml2js does not process DTDs by default, but ensure no external parsing hooks are added
  trim: true,
  normalize: true,
  explicitCharkey: false,
  attrkey: 'attributes',
  charkey: '_text',
  // Avoid custom entity resolvers
  entityReplacementPattern: /[\0-\x08\x0B\x0C\x0E-\x1F\x7F]/g
});

// In an AdonisJS controller handle method
async store({ request, response) {
  const xml = request.input('xml');
  try {
    const result = await parser.parseStringPromise(xml);
    // Validate/sanitize result before storing
    await Database.collection('imports').insertOne(result);
    return response.ok({ stored: true });
  } catch (err) {
    // Handle parse errors securely
    return response.badRequest({ error: 'Invalid XML' });
  }
}

If you use fast-xml-parser, explicitly disable external entities and DTD processing:

const { XMLParser } = require('fast-xml-parser');

const parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: '_',
  textNodeName: '#text',
  // Ensure no external subset or DTD processing
  allowBooleanAttributes: true,
  parseNodeValue: true,
  parseAttributeValue: false,
  trimValues: true,
  // Reject DOCTYPE and entity declarations
  doctype: false,
  validation: false
});

async store({ request, response }) {
  const xml = request.input('xml');
  if (!parser.validate(xml)) {
    return response.badRequest({ error: 'Invalid XML' });
  }
  const jsonObj = parser.parse(xml);
  // Apply additional schema checks here
  await Database.collection('imports').insertOne(jsonObj);
  return response.ok({ stored: true });
}

Schema validation and sanitization before MongoDB insertion

Use a validation library to enforce strict shape checks and strip unexpected or dangerous fields, including those that could carry entity references or executable content:

const { schemaValidator } = require('@adonisjs/validator');

const importSchema = schemaValidator.create({
  type: 'object',
  required: ['name', 'payload'],
  properties: {
    name: { type: 'string', maxLength: 255 },
    payload: {
      type: 'object',
      additionalProperties: true,
      // Avoid allowing raw XML or DTD-like strings
      properties: {
        data: { type: 'string', pattern: '^[^<>]*$' },
        fileUrl: { type: 'string', format: 'uri' }
      }
    }
  }
});

async store({ request, response }) {
  const payload = request.only(['name', 'payload']);
  const validated = importSchema.validate(payload);
  if (!validated.success) {
    return response.badRequest({ errors: validated.errors });
  }
  // Safe insert into MongoDB
  await Database.collection('imports').insertOne(validated.data);
  return response.created(validated.data);
}

Secure MongoDB client usage and query patterns

When reading data for exports or UI, avoid passing raw user input directly into MongoDB queries that could reconstruct XML or interpret entity references. Use parameterized queries and projection to limit returned fields:

const ObjectId = require('mongodb').ObjectId;

async show({ params, response }) {
  const id = params.id;
  if (!ObjectId.isValid(id)) {
    return response.badRequest({ error: 'Invalid ID' });
  }
  const doc = await Database.collection('imports').findOne(
    { _id: new ObjectId(id) },
    { projection: { name: 1, createdAt: 1, payload: 1 } }
  );
  if (!doc) {
    return response.notFound({ error: 'Not found' });
  }
  // Do not re-serialize as XML without disabling DTDs if client expects XML
  return response.ok(doc);
}

Additional operational practices

  • Keep parser dependencies up to date and monitor for known vulnerabilities.
  • Reject XML inputs that contain DOCTYPE or entity declarations at the API gateway or via parser options.
  • Apply the same validation when consuming data from MongoDB, especially if it is re-exported as XML or used in internal integrations.

Frequently Asked Questions

Can XXE occur if my AdonisJS app only uses JSON APIs?
Yes, if you accept XML payloads or process XML files (e.g., uploads or imports) and pass parsed data to MongoDB. JSON-only endpoints are not at risk from XXE, but file imports or XML-based integrations can introduce the vector.
Does middleBrick detect XXE in AdonisJS with MongoDB?
middleBrick scans unauthenticated attack surfaces and can surface related findings such as injection risks and data exposure patterns. Use the CLI (middlebrick scan ) or Web Dashboard to review category breakdowns and remediation guidance; findings map to frameworks like OWASP API Top 10.