VNX-652: XQuery injection
Reports a Java XQuery (XQJ, Saxon, BaseX, eXist/XML:DB, MarkLogic XCC) query built by concatenation or formatting of a non-constant value and passed to the engine.
| Field | Value |
|---|---|
| Rule ID | VNX-652 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Java |
| CWE | CWE-652 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | xquery injection cwe-652 |
| Source | internal/sast/rules/vnx-652.rego |
Overview
VNX-652 maps to CWE-652: Improper Neutralization of Data within XQuery Expressions. In Java files that use an XQuery API (javax.xml.xquery, net.sf.saxon, org.basex, org.xmldb, com.marklogic.xcc) it reports executeQuery, prepareExpression, executeCommand, compile, query, execute, newAdhocQuery, new XQuery(...) and new QueryProcessor(...) whose argument:
- concatenates a variable, parameter or method result into a string literal,
- uses
String.format,.formattedorMessageFormat.format, or - is a variable or
StringBuilder.toString()built that way in the ten lines above (including a concatenation broken across lines).
Not reported: external variables bound with bindString/bindObject, constant queries and concatenation of literals or UPPER_CASE constants, SQL passed to JDBC, files without an XQuery API, comments and the call inside a string literal.
Why This Matters
A value such as ' or '1'='1 or '] | doc('secrets.xml')//*[' rewrites the query, returning documents the caller should not see, and with some engines (BaseX, MarkLogic) reaching file and HTTP functions.
What Gets Flagged
// FLAGGED
return expr.executeQuery("for $b in doc('books.xml')//book where $b/author = '" + req.getParameter("author") + "' return $b");
String query = "doc('users.xml')/users/user[name='" + username + "']";
XQPreparedExpression pe = conn.prepareExpression(query); // FLAGGED
return compiler.compile(String.format("//sale[region='%s']", region)); // FLAGGED
// NOT FLAGGED: external variable
XQPreparedExpression pe = conn.prepareExpression("declare variable $author external; //book[author = $author]");
pe.bindString(new QName("author"), author, null);
Remediation
- Declare
externalvariables in the query and bind values (bindString, SaxonXQueryEvaluator.setExternalVariable, BaseXbind). - Never build the query text from request data.
References
- CWE-652: Improper Neutralization of Data within XQuery Expressions
- OWASP Injection Prevention Cheat Sheet
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-652
// nosec vnx-652
Or record an ignore rule: vulnetix ignore add --rule vnx-652 --reason "...". See Suppressing findings.