Xpath Injection in Express with Dynamodb
Xpath Injection in Express with Dynamodb — how this specific combination creates or exposes the vulnerability
XPath Injection is a classic injection class where untrusted input alters the semantics of an XPath expression. While XPath is not commonly used with DynamoDB, an Express API that builds XPath-like strings to query XML or JSON-as-XML (for example via transformation layers or legacy integrations) can expose this vulnerability. The risk arises when user-controlled data is concatenated into an XPath expression without proper escaping or parameterization, and the resulting expression is then used to traverse XML structures that may be derived from or validated against a DynamoDB-stored schema or configuration.
Consider an Express endpoint that retrieves user preferences stored in DynamoDB and then uses an XPath selection over an XML representation of those preferences. If the field or attribute name is derived from client input, an attacker can inject additional path segments. For example, an input like profile/* or " or "1"="1 can change the selection logic, potentially accessing other users’ data or extracting unexpected elements. In a DynamoDB context, this typically means the data stored as JSON is first converted to an XML DOM for legacy processing; if that conversion is naive and the resulting XPath is built by string concatenation, the injection surface exists.
The DynamoDB item itself does not execute XPath, but if your Express service uses items from DynamoDB to construct dynamic XPath expressions—such as selecting nodes from an XML document derived from a stored document or configuration—unchecked input leads to unauthorized data exposure or bypass of intended access controls. This pattern is especially risky when combined with overly permissive IAM policies on the DynamoDB table, as the injected XPath may retrieve items the caller should not see.
middleBrick’s unauthenticated scan would flag this as an Injection and Authorization issue, identifying places where input validation is insufficient for XPath construction and where DynamoDB-stored data flows into XML processing logic. The scan does not fix the code, but it provides prioritized findings with severity, context, and remediation guidance to help you address the root cause.
Dynamodb-Specific Remediation in Express — concrete code fixes
Remediation focuses on two layers: preventing XPath string construction from untrusted input, and safely integrating DynamoDB data into XML workflows. Do not build XPath expressions by concatenating user-controlled values. Use a dedicated XPath library that supports parameterization or compile-time construction, and treat data from DynamoDB as untrusted when it is used in downstream XML processing.
Below is a safe Express pattern that retrieves an item from DynamoDB and, if XML processing is required, uses a controlled mapping rather than dynamic XPath injection.
const express = require('express');
const { DynamoDBClient, GetItemCommand } = require('@aws-sdk/client-dynamodb';
const { unmarshall } = require('@aws-sdk/util-dynamodb');
const { parseStringPromise } = require('xml2js');
const app = express();
const client = new DynamoDBClient({ region: 'us-east-1' });
app.get('/preferences/:userId', async (req, res) => {
const userId = req.params.userId;
// Validate and sanitize userId; do not use it to build XPath strings
if (!/^\w{1,20}$/.test(userId)) {
return res.status(400).send('Invalid user identifier');
}
const cmd = new GetItemCommand({
TableName: 'UserPreferences',
Key: { userId: { S: userId } }
});
try {
const { Item } = await client.send(cmd);
const data = unmarshall(Item);
// Assume storedPreferences.xml is a safe, server-side template or transformed document
const xml = data.preferencesXml; // stored as string in DynamoDB
const parsed = await parseStringPromise(xml, { explicitArray: false });
// Use a fixed, known path; never inject userId or any client value into XPath
const preferredTheme = parsed.preferences.theme?.[0] || 'default';
res.json({ theme: preferredTheme });
} catch (err) {
console.error(err);
res.status(500).send('Internal error');
}
});
app.listen(3000, () => console.log('Server running on port 3000'));If you must filter or select within server-side XML that originates from DynamoDB, use DOM methods with index-based access or whitelisted element names rather than building expressions from raw input. For example, use document.evaluate with a compiled, static expression and pass user values only as XPath function arguments if your runtime supports it, or filter nodes by property values in application code after retrieving the node list.
Additionally, enforce least-privilege IAM policies on the DynamoDB table so that even if an XPath injection were possible, the scope of accessible items would be limited. middleBrick’s Pro plan supports continuous monitoring and CI/CD integration to help ensure that such unsafe patterns are caught before deployment.