HIGH xpath injectionexpresscockroachdb

Xpath Injection in Express with Cockroachdb

Xpath Injection in Express with Cockroachdb — how this specific combination creates or exposes the vulnerability

XPath Injection occurs when an attacker can influence the structure or data of an XPath expression constructed from untrusted input. In an Express application using CockroachDB, this typically arises when building XPath queries dynamically using string concatenation or interpolation with user-controlled values such as query parameters, headers, or JSON payloads.

CockroachDB supports PostgreSQL wire protocol and commonly stores structured data that may be queried via XPath when XML or JSON data types are used. If an endpoint constructs an XPath expression by embedding user input without proper escaping or validation, an attacker can alter the XPath logic. For example, an input like ' or '1'='1 can change the predicate logic, potentially bypassing intended filters or extracting unintended data nodes.

The combination of Express (a Node.js web framework) and CockroachDB increases risk when developers use dynamic XPath construction to query XML or JSON fields stored in the database. Unlike parameterized SQL queries, XPath does not have native parameterized query support in many libraries, encouraging unsafe string building. This opens paths for unauthorized data access, authentication bypass, or data exfiltration via modified XPath results.

Consider an endpoint that retrieves user settings stored as XML:

const { parseStringPromise } = require('xml2js');
const db = require('cockroachdb');

app.get('/settings', async (req, res) => {
  const userId = req.query.userId;
  const xpathQuery = `//settings/user[@id='${userId}']`;
  const result = await db.query('SELECT xml_data FROM users WHERE id = $1', [userId]);
  const xml = result.rows[0].xml_data;
  const json = await parseStringPromise(xml, { explicitArray: false });
  const settings = json.settings.user;
  res.json(settings);
});

Here, userId is directly interpolated into the XPath expression. An attacker supplying ?userId=1' or true() or '@'=' can manipulate the XPath to return multiple or all user nodes, leading to privilege escalation or data exposure. Even though the SQL query uses a parameterized statement, the XPath construction remains unsafe.

middleBrick scans such endpoints and flags unsafe XPath construction as part of its Input Validation and Property Authorization checks, highlighting the need to treat XPath with the same rigor as SQL or NoSQL queries.

Cockroachdb-Specific Remediation in Express — concrete code fixes

To prevent XPath Injection when using CockroachDB in Express, avoid building XPath expressions via string interpolation. Instead, use defensive parsing, strict input validation, and server-side filtering. Below are concrete, safe patterns.

1. Use whitelisted identifiers and strict validation

Validate user input against a strict allowlist before using it in any logic. For IDs, enforce integer or UUID formats:

const { validationResult } = require('express-validator');

app.get('/settings', [
  param('userId').isUUID()
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  const userId = req.params.userId;
  const result = await db.query('SELECT xml_data FROM users WHERE id = $1', [userId]);
  const xml = result.rows[0].xml_data;
  const json = await parseStringPromise(xml, { explicitArray: false });
  res.json(json.settings.user);
});

2. Avoid XPath for user-driven selection; use JSON path or server-side filtering

If your data is JSON, prefer JSON path with strict path templates instead of dynamic XPath:

const jsonPath = require('jsonpath');

app.get('/settings/:userId', async (req, res) => {
  const userId = req.params.userId;
  const result = await db.query('SELECT json_data FROM users WHERE id = $1', [userId]);
  const jsonData = result.rows[0].json_data;
  const settings = jsonPath.query(jsonData, `$..users[?(@.id == '${userId}')].settings`);
  res.json(settings[0] || null);
});

Even when using JSON paths, ensure the path structure is static and only values are parameterized.

3. Use server-side filtering after retrieving a small, trusted dataset

Fetch a minimal dataset and filter in application code:

app.get('/settings/:userId', async (req, res) => {
  const userId = req.params.userId;
  const result = await db.query('SELECT xml_data FROM users');
  const rows = result.rows;
  const parser = new xml2js.Parser({ explicitArray: false });
  let found = null;
  for (const row of rows) {
    const parsed = await parser.parseStringPromise(row.xml_data);
    const userNode = parsed.settings.user.find(u => u.id === userId);
    if (userNode) {
      found = userNode;
      break;
    }
  }
  res.json(found || null);
});

This approach eliminates XPath injection entirely by removing dynamic XPath construction. middleBrick’s scans verify that no user input directly influences query construction, aligning with its BOLA/IDOR and Input Validation checks.

4. If XPath is unavoidable, use compiled expressions with strict variable binding

Some XPath libraries allow creating compiled expressions with variable placeholders. Prefer these over string concatenation:

const xpath = require('xpath');
const dom = require('xmldom').DOMParser;

app.get('/data', async (req, res) => {
  const userId = req.query.userId;
  const result = await db.query('SELECT xml_data FROM profiles WHERE role = $1', ['admin']);
  const doc = new dom().parseFromString(result.rows[0].xml_data);
  const expr = xpath.compile('//profile[@user-id=$userId]');
  const nodes = expr.evaluate(doc, xpath.XPathResultType.NODESET, null, xpath.nsResolver, { userId });
  let node;
  const results = [];
  while ((node = nodes.iterateNext())) results.push(node);
  res.json(results);
});

Ensure your XPath library supports variable binding; if not, filtering in application code is safer.

middleBrick’s LLM/AI Security checks also ensure that no prompt or configuration exposes unsafe query-building patterns, reinforcing defense-in-depth.

Frequently Asked Questions

Can middleBrick detect XPath Injection in my Express endpoints?
Yes, middleBrick runs Input Validation and Property Authorization checks that flag unsafe XPath construction and dynamic query building.
Does using CockroachDB change how I should handle user input in XPath?
No. Regardless of the database, avoid building XPath via string interpolation. Use strict validation, server-side filtering, or compiled expressions with bound variables.