Skip to content

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.

Updated 02 Nov 2026Checked against cli@de9b52a
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, .formatted or MessageFormat.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

  1. Declare external variables in the query and bind values (bindString, Saxon XQueryEvaluator.setExternalVariable, BaseX bind).
  2. Never build the query text from request data.

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-652
// nosec vnx-652

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

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