Xpath Injection in Adonisjs with Firestore
Xpath Injection in Adonisjs with Firestore — how this specific combination creates or exposes the vulnerability
XPath Injection occurs when untrusted data is concatenated into an XPath expression without proper sanitization or parameterization, allowing an attacker to alter the query logic. AdonisJS, a Node.js web framework, does not provide built-in XPath utilities, so developers typically integrate external libraries to query XML or systems that expose XPath-like semantics. When Firestore is used in an AdonisJS application, the risk arises if the app builds dynamic queries or document paths by interpolating user input into strings that are later interpreted as selectors or keys.
Although Firestore itself does not use XPath, an AdonisJS service might construct Firestore document paths, collection groups, or filter values using string concatenation based on request parameters. If these values are used to form XPath-like expressions—for example, when transforming Firestore document references into XML representations for legacy integrations—or when input is used to build queries that emulate hierarchical traversal, attackers can inject malicious segments. A typical vulnerable pattern is:
const username = request.input('username');
// Dangerous: direct concatenation into an XPath-like selector
const xpath = `/users/user[username='${username}']`;
// Later used in an XML parser or transformed into a Firestore document path
const result = await firestore.collection('users').doc(username).get();
An attacker supplying ' or username='admin' or '' as the username can manipulate the logical structure of the expression, potentially bypassing intended access controls or enumerating documents. Even when Firestore operations are parameterized, the surrounding AdonisJS code might log, transform, or forward user-controlled strings into secondary systems that do interpret XPath, expanding the blast radius. The unauthenticated attack surface of an AdonisJS endpoint that accepts identifiers and builds dynamic paths is therefore exposed, as Firestore permissions may not restrict traversal patterns encoded in XPath-like strings.
XPath Injection in this context is less about querying Firestore and more about how AdonisJS handles and exposes identifiers in contexts where string-based selectors are interpreted. Because Firestore rules rely on exact document paths and collection names, injection can lead to path traversal or privilege escalation when combined with weak validation. For instance, an attacker might supply a path segment like ../../../config to access unintended resources if the application does not canonicalize or validate document references. This highlights the importance of validating and encoding all user-supplied input before it participates in any selector or path construction, whether the target is an XML parser or a Firestore document lookup.
Firestore-Specific Remediation in Adonisjs — concrete code fixes
To prevent Xpath Injection when working with Firestore in AdonisJS, treat all user input as untrusted and avoid building document paths or selectors via string concatenation. Use parameterized approaches, strict validation, and canonicalization. The following examples demonstrate secure patterns.
1. Validate and sanitize identifiers
Restrict document IDs to a safe character set and length. Use a validation schema to reject unexpected characters.
const schema = use('Validator')
const rules = {
username: 'required|alpha_dash|max:32',
}
const { username } = await schema.validate(request.all())
2. Use Firestore’s native methods with parameterized inputs
Always pass identifiers directly to Firestore methods rather than embedding them in strings. This ensures paths are handled safely by the SDK.
const { username } = request.params()
// Safe: document ID is passed as a value, not interpolated into a path string
const docRef = firestore.collection('users').doc(username)
const snapshot = await docRef.get()
if (!snapshot.exists) {
throw new Error('User not found')
}
const data = snapshot.data()
3. Avoid XPath-like construction entirely
If integrating with systems that require XPath, construct expressions using a dedicated library with parameterized binding instead of string interpolation.
// Example using a hypothetical XPath builder (not Firestore-specific)
const createXPath = require('xpath-builder')
const safeXPath = createXPath('/users/user').where('username').equals(sanitizedUsername)
// Use safeXPath only in contexts that require XML/XPath
4. Apply principle of least privilege in Firestore rules
Ensure Firestore security rules validate document access strictly and do not rely on client-supplied path components for authorization logic.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
5. Encode outputs when transforming data for external systems
If Firestore data must be serialized into formats that support XPath or hierarchical queries, encode special characters to neutralize injection vectors.
const escapeForXPath = (value) => {
return value.replace(/'/g, "''")
}
const safeValue = escapeForXPath(userSuppliedString)
By combining strict input validation, direct Firestore SDK usage, and careful handling when interfacing with external query languages, AdonisJS applications can mitigate Xpath Injection risks while interacting with Firestore.