Skip to content

VNX-112: Missing XML Validation

XML received in an HTTP request is parsed (DocumentBuilder, JAXB, StAX, lxml/ElementTree, minidom, xmltodict, xml2js, libxmljs, DOMParser, fast-xml-parser) in a file with no schema or structural validation.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-112
Severity High
SARIF level error
Kind sast
Languages Java, JavaScript / TypeScript, Python
CWE CWE-112
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:H/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H
Tags xml validation schema cwe-112
Source internal/sast/rules/vnx-112.rego

Overview

VNX-112 maps to CWE-112: Missing XML Validation. It reports an XML parse whose input is the request body or a request value, used directly or through a variable assigned from it in the 25 lines above, in a file whose code never validates the document:

  • Java DocumentBuilder/SAXParser/XMLReader .parse, JAXB .unmarshal, StAX createXMLStreamReader/createXMLEventReader
  • Python lxml/ElementTree/defusedxml fromstring/XML/parse, minidom.parseString, xmltodict.parse, untangle
  • Node xml2js parseString/parseStringPromise, libxmljs parseXml/parseXmlString, DOMParser.parseFromString, xml-js, fast-xml-parser XMLParser.parse

A file that mentions schema validation in code (setSchema, SchemaFactory, Validator, .validate(, setValidating(true), XMLSchema, schema=, an XSD, or a schema check of the parsed result) is not reported, nor is XML read from files or constants. External-entity (XXE) handling is a separate weakness with its own rules.

Why This Matters

Code that reads doc.getElementsByTagName("qty").item(0) assumes the element exists, appears once and holds a number. Without validation the requester decides all of that: missing or repeated elements, unexpected types and oversized content reach business logic, causing crashes, logic bypasses (a second <price> element read by one component and ignored by another) and injection further downstream.

What Gets Flagged

Document doc = db.parse(request.getInputStream());                 // FLAGGED
Order order = (Order) u.unmarshal(new StringReader(body));         // FLAGGED (@RequestBody String body)
root = etree.fromstring(request.data, parser)                      # FLAGGED
doc = minidom.parseString(request.body)                            # FLAGGED
xml2js.parseString(req.body, (err, result) => { /* ... */ });      // FLAGGED
const doc = parser.parse(req.body as string);                      // FLAGGED (fast-xml-parser)

Not flagged: dbf.setSchema(schema) in the same file, etree.XMLParser(schema=SCHEMA), a Joi feedSchema.validate(result) of the parsed document, ET.parse("config/settings.xml").

Remediation

  1. Validate request XML against an XSD before using it: DocumentBuilderFactory.setSchema()/Unmarshaller.setSchema() in Java, etree.XMLParser(schema=...) or XMLSchema.assertValid() in lxml, doc.validate(xsd) in libxmljs.
  2. Or validate the parsed structure with a schema library (Joi, ajv, pydantic) before reading fields from it.
  3. Reject documents that fail validation with a 400 response; never fall back to using them.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-112
// nosec vnx-112

Or record an ignore rule: vulnetix ignore add --rule vnx-112 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-112.rego, cli/internal/sast/docs/vnx-112.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.