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.
| 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, StAXcreateXMLStreamReader/createXMLEventReader - Python lxml/ElementTree/defusedxml
fromstring/XML/parse,minidom.parseString,xmltodict.parse,untangle - Node
xml2jsparseString/parseStringPromise,libxmljsparseXml/parseXmlString,DOMParser.parseFromString,xml-js, fast-xml-parserXMLParser.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
- Validate request XML against an XSD before using it:
DocumentBuilderFactory.setSchema()/Unmarshaller.setSchema()in Java,etree.XMLParser(schema=...)orXMLSchema.assertValid()in lxml,doc.validate(xsd)in libxmljs. - Or validate the parsed structure with a schema library (Joi, ajv, pydantic) before reading fields from it.
- 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.