HIGH xpath injectionexpressapi keys

Xpath Injection in Express with Api Keys

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

XPath Injection occurs when user input is concatenated into an XPath expression without proper sanitization or parameterization, allowing an attacker to alter the logic of the query. In an Express application that relies on XML data sources and uses API keys for access control, the combination can expose two related risks: data exposure via XPath traversal and privilege confusion due to weak key validation.

Consider an endpoint that resolves a user profile XML document using an XPath expression built from an untrusted query parameter, for example a username or user ID. If the code constructs the path by string interpolation, an attacker can supply input such as ' or 1=1 or ' to change the predicate logic and potentially return nodes they should not see. Because the Express route uses API keys to gate access, developers may assume authorization is already enforced; however, if the API key is only checked before the XPath is built, the attacker can still manipulate the query to return sensitive data once they possess a valid key. This shifts the issue from authentication bypass to data exposure within the authorized context.

Another scenario involves document updates or deletions where the XPath selects nodes based on an identifier provided by the client. A malicious payload can extend the predicate to affect multiple nodes or inject functions like contains() to widen the selection set. Because XPath operates on the structure of the XML, successful injection can lead to reading or modifying more data than intended. The API key does not sanitize the input; it only identifies the client, so the server must still treat all input as untrusted. This aligns with the OWASP API Top 10 category for Broken Object Level Authorization (BOLA) and highlights why input validation and output encoding must be applied regardless of authentication or key checks.

Api Keys-Specific Remediation in Express — concrete code fixes

To mitigate XPath Injection in Express while using API keys, avoid building XPath expressions through string concatenation. Use a library that supports parameterized XPath or transform the input into a safe selection without injecting raw values.

Example of vulnerable code:

const express = require('express');
const router = express.Router();
const { parseString } = require('xml2js');
const xpath = require('xpath');
const { DOMParser } = require('xmldom');

router.get('/profile', (req, res) => {
  const apiKey = req.headers['x-api-key'];
  const username = req.query.username;

  if (!apiKey || apiKey !== process.env.API_KEY) {
    return res.status(401).send('Unauthorized');
  }

  // Vulnerable: building XPath via concatenation
  const expr = `//user[name="${username}"]`;
  const doc = new DOMParser().parseFromString(xmlData);
  const nodes = xpath.select(expr, doc);

  res.json(nodes);
});

Fix by validating and encoding the input, and by avoiding dynamic concatenation where possible. One approach is to select all candidates and filter in JavaScript, which removes the XPath injection surface while still enforcing the API key check:

router.get('/profile', (req, res) => {
  const apiKey = req.headers['x-api-key'];
  const username = req.query.username;

  if (!apiKey || apiKey !== process.env.API_KEY) {
    return res.status(401).send('Unauthorized');
  }

  if (!username || typeof username !== 'string' || !/^[A-Za-z0-9_]{1,64}$/.test(username)) {
    return res.status(400).send('Invalid username');
  }

  const doc = new DOMParser().parseFromString(xmlData);
  const nodes = xpath.select('//user', doc);
  const filtered = nodes.filter(node => node.name[0] === username);

  res.json(filtered);
});

If you must use XPath predicates, ensure the input is properly escaped or use a library that supports variable binding. For example, with xpath.js you can avoid injection by not interpolating the value into the expression string directly. Treat API keys as identifiers only, and enforce strict input validation and encoding to protect against XPath-level data exposure.

Frequently Asked Questions

Why does using an API key not prevent XPath Injection in Express?
API keys authenticate the client but do not sanitize input. If the server builds XPath expressions by concatenating user-controlled values, an attacker can manipulate the query logic even when a valid key is present. Proper input validation and safe selection methods are required.
What validation pattern is recommended for usernames in Express to prevent injection?
Use strict allow-lists with regular expressions, for example /^[A-Za-z0-9_]{1,64}$/, and avoid passing raw input into XPath or any query language. Combine this with parameterized selection or in-memory filtering to eliminate injection risks.