Xpath Injection in Express with Basic Auth
Xpath Injection in Express with Basic Auth
Xpath Injection in an Express API that uses HTTP Basic Authentication occurs when user-controlled input is concatenated into XPath expressions without sanitization or parameterized queries. In this combination, the attacker must first bypass or ignore the Basic Auth layer (for example, by discovering an unauthenticated endpoint, finding credentials via source code or browser history, or exploiting weak password policies), then inject crafted strings into parameters that are used to build dynamic XPath queries on the server side.
Consider an Express route that authenticates via Basic Auth and then uses a username from the request to look up a user record in an XML data store using XPath. If the username is taken directly from query parameters or headers and concatenated into the XPath string, an attacker can escape the intended context and alter the logic of the query. For instance, a username like admin' or '1'='1 can modify a predicate to always return true, potentially bypassing intended access controls or extracting other users’ data. This is similar in effect to SQL Injection but applied to the XML data model, and it can lead to authentication bypass, information disclosure, or unauthorized data modification.
In a black-box scan, middleBrick tests the unauthenticated attack surface by attempting to discover authentication mechanisms and then probes endpoints that accept user input in XPath-influencing positions. When Basic Auth is present but misconfigured or partially bypassed, and XPath is built dynamically, the scanner can inject payloads such as ' or 1=1 or ' or substring(//password,1,1)='a to test for boolean-based and blind injection. Findings may map to the OWASP API Top 10 category Broken Object Level Authorization (BOLA/IDOR) and Input Validation, depending on how the injected data influences access decisions or data exposure.
An example of vulnerable Express code illustrates the problem. The route uses the basic-auth package to parse credentials and then builds an XPath expression by string concatenation:
const basicAuth = require('basic-auth');
const { parseString } = require('xml2js');
const xpath = require('xpath');
const { DOMParser } = require('xmldom');
app.get('/user', (req, res) => {
const creds = basicAuth(req);
if (!creds || creds.name !== 'admin' || creds.pass !== 'secret') {
return res.status(401).send('Unauthorized');
}
const username = req.query.username;
const xml = '<users><user><name>alice</name><role>user</role></user><user><name>admin</name><role>admin</role></user></users>';
const doc = new DOMParser().parseFromString(xml);
const expr = `//user[name='${username}']/role`;
const nodes = xpath.select(expr, doc);
res.json({ role: nodes.map(n => n.textContent) });
});
If the username query parameter is controlled by an attacker and the XPath is built via concatenation, they could supply admin' or '1'='1 (or a properly escaped variant depending on the XPath dialect) to manipulate the predicate. Even with Basic Auth correctly enforced, if the authentication check is incomplete or if the endpoint is accidentally exposed without auth, the injection becomes more impactful. middleBrick’s LLM/AI Security checks are especially relevant here because an attacker might attempt to coax the server into leaking internal logic or data via crafted inputs that influence both authentication and XPath behavior.
To summarize, the combination of Express, Basic Auth, and dynamic XPath creates risk when input is not strictly separated from query logic. The presence of authentication does not automatically prevent injection if the endpoint is reachable and the XPath is constructed unsafely. Defense requires strict input validation, parameterized XPath APIs, and careful handling of credentials to ensure that auth checks cannot be bypassed and that injected fragments cannot alter query semantics.
Basic Auth-Specific Remediation in Express
Remediation focuses on eliminating string concatenation in XPath construction, enforcing strong authentication, and validating input. Use a parameterized XPath library when available, or manually escape and validate input to ensure it cannot change the structure of the expression. For Express with Basic Auth, always validate credentials before processing any user-supplied data, and keep authentication logic separate from data access logic.
First, enforce robust Basic Auth validation. Use the basic-auth package to extract credentials and compare them safely:
const basicAuth = require('basic-auth');
function verifyAuth(req, res, next) {
const creds = basicAuth(req);
const validUser = creds && creds.name === process.env.ADMIN_USER && creds.pass === process.env.ADMIN_PASS;
if (!validUser) {
res.set('WWW-Authenticate', 'Basic realm="example"');
return res.status(401).send('Authentication required');
}
next();
}
Apply verifyAuth as middleware to routes that require protection. This keeps authentication explicit and avoids accidental exposure.
Second, avoid concatenating user input into XPath. Prefer libraries that support compiled or parameterized expressions; if unavailable, rigorously validate and escape input. For example, allow only alphanumeric usernames and reject any characters outside that set:
const allowedUsername = /^[a-zA-Z0-9_]+$/;
app.get('/user', verifyAuth, (req, res) => {
const username = req.query.username;
if (!allowedUsername.test(username)) {
return res.status(400).send('Invalid username');
}
const xml = '<users>...</users>';
const doc = new DOMParser().parseFromString(xml);
// Use a safe selection method if the library supports it:
// const nodes = xpath.select(xpath.compile('//user[name=$username]/role'), doc, { username });
// If parameterized compilation is not available, strict validation is critical.
const expr = `//user[name='${username}']/role`;
const nodes = xpath.select(expr, doc);
res.json({ role: nodes.map(n => n.textContent) });
});
Third, consider storing sensitive access rules server-side and mapping usernames to roles via a controlled lookup rather than relying on XPath predicates that can be manipulated. Combine this with rate limiting and monitoring to reduce brute-force risks against the Basic Auth layer. middleBrick’s Pro plan supports continuous monitoring and GitHub Action integration, which can help detect regressions in authentication or input handling during CI/CD runs.
Finally, test the API with tools that simulate injection attempts against both authenticated and unauthenticated paths. Ensure that even when credentials are valid, malformed input cannot alter query behavior. Regular scans using the middleBrick CLI can provide automated feedback on whether your endpoints remain resilient against Xpath Injection and related input validation issues.