Skip to content

UntrustedXmlExternalEntityExpansion ​

warning native on by default

Group: Security

Expanding external entities in request-controlled XML can expose external resources. Disable that capability for untrusted documents.

Example ​

php
<?php
$d=new DOMDocument(); $d->loadXML($_POST["xml"],LIBXML_NOENT|LIBXML_DTDLOAD);

Reported:

  • line 2: Disable external entity expansion for request-controlled XML.

Detection ​

  • Resolved DOMDocument::loadXML receives direct request-superglobal data and options definitely contain both LIBXML_NOENT and LIBXML_DTDLOAD, without a supported LIBXML_NO_XXE option. LIBXML_NONET alone does not suppress: it blocks network resources but permits other external resource access. Report explicit external entity access capability. The no-XXE bit suppresses only for PHP 8.4 or later; the same numeric bit on PHP 8.3 or earlier does not establish protection.
  • Input must be a directly written array-field access on $_GET, $_POST, $_REQUEST or $_COOKIE. Stored local values and other superglobals are excluded.
  • Inspect at most 64 preceding statements in the same straight-line lexical prefix. Each must be an ordinary, non-reference simple-local assignment whose value is a resolved new DOMDocument expression with no constructor arguments. The assignment target must not be the same request-superglobal variable used by the input access. Any other preceding operation discards the untouched-input proof, including superglobal writes, sanitization calls and unknown operations. Constructors with any arguments are excluded, including otherwise harmless literal arguments, to keep the request-source proof conservative.
  • Resolve builtin functions, classes, constants and methods; user-defined lookalikes are excluded. Follow only bounded local proof in one lexical scope.
  • Emit one finding per violating operation, not per supporting evidence statement. When the proof is inconclusive, nothing is reported.

Exceptions (no report) ​

  • Do not report unresolved or shadowed builtin names, unknown values, or incomplete receiver/type provenance. Unknown calls, aliases escaping, and intervening writes invalidate local proof. Similar code outside the stated detection contract is not a finding.
  • Both standard suppression forms suppress this native ID.

Fix ​

None. Choosing a repair requires intent or additional runtime information.

PHP versions ​

Available throughout supported PHP 5.3–8.5 when DOM/libxml is available. Treat LIBXML_NO_XXE as protection only on PHP 8.4 or later; a numeric no-XXE bit on an earlier target does not suppress the finding. LIBXML_NONET alone does not establish protection against local external resources.

Configure ​

In custos.json:

json
{
  "rules": {
    "UntrustedXmlExternalEntityExpansion": {
      "enabled": false
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore UntrustedXmlExternalEntityExpansion

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.