Path Traversal in Hapi with Firestore
Path Traversal in Hapi with Firestore — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when an endpoint uses user-controlled input to construct a file or document path without proper validation, allowing an attacker to access files or Firestore documents outside the intended directory or collection. In a Hapi application that integrates with Cloud Firestore, this typically manifests through route parameters, query strings, or request bodies that directly reference document IDs or collection paths.
Firestore does not have a traditional filesystem, but Path Traversal can still occur when a developer concatenates user input into a document path or uses a predictable document ID scheme. For example, if a route like /users/{userId}/profile uses userId directly to fetch a document from a users collection without validation, an attacker could provide a value such as ../../../admin/settings to attempt to traverse logical boundaries and access sensitive documents. While Firestore enforces strict rules, the application layer must ensure that IDs and paths are constrained to expected formats.
Hapi routes often pass parameters directly into Firestore SDK calls. If input is not strictly validated or sanitized, this creates an unauthenticated attack surface. The scanner’s BOLA/IDOR and Input Validation checks can detect whether endpoints allow traversal-like patterns, such as encoded path segments or unexpected delimiters. Because Firestore permissions rely on correct document referencing, an unintended path can expose data that the rules do not explicitly protect, especially in configurations where rules are permissive during development.
Another scenario involves listing or batch operations where a client-supplied prefix is used to query subcollections. If an endpoint builds a query using user input like req.params.store to form a collection group path, an attacker might supply values such as users/otherUser/orders to enumerate data across tenants. Even with Firestore security rules, improperly constrained queries can return more data than intended when path components are not validated against the expected resource hierarchy.
middleBrick’s LLM/AI Security checks are not relevant to this specific vulnerability, but its Inventory Management and Input Validation checks help identify risky endpoint designs where user-controlled path components reach Firestore queries. The scanner also cross-references OpenAPI specs with runtime behavior to highlight parameters that could lead to document path manipulation without authentication.
To mitigate, always validate and sanitize all user input used in document references. Enforce strict allowlists for IDs, avoid dynamic path concatenation, and prefer using Firestore’s built-in document ID mechanisms. Regular scanning with a tool that tests unauthenticated attack surfaces can uncover these issues before they reach production.
Firestore-Specific Remediation in Hapi
Secure Hapi integrations with Firestore require strict control over how document references are built. Instead of directly interpolating route parameters into document paths, validate and normalize input to ensure it conforms to expected patterns. Use Firestore’s doc and collection helpers with hardcoded or mapped identifiers rather than raw user input.
Below is a vulnerable Hapi route that demonstrates the risk:
// Vulnerable example
server.route({
method: 'GET',
path: '/api/users/{userId}',
handler: async (request, h) => {
const { userId } = request.params;
const doc = await firestore.doc(`users/${userId}`).get();
return doc.data();
}
});
An attacker could supply userId=../../../admin and potentially access unintended data if validation is absent. The following remediation applies strict validation and uses a mapping layer to avoid direct path concatenation:
// Secured example with validation
const validUserIds = new Set(['alice', 'bob', 'charlie']); // Example allowlist
server.route({
method: 'GET',
path: '/api/users/{userId}',
handler: async (request, h) => {
const { userId } = request.params;
if (!validUserIds.has(userId)) {
throw Boom.badRequest('Invalid user identifier');
}
const doc = await firestore.doc(`users/${userId}`).get();
if (!doc.exists) {
throw Boom.notFound();
}
return doc.data();
}
});
For dynamic collections such as tenant-aware data, use a controlled mapping instead of raw input:
// Secured example with mapped collection reference
const tenantId = request.auth.credentials.tenantId; // From authentication
server.route({
method: 'GET',
path: '/api/tenants/{recordId}',
handler: async (request, h) => {
const { recordId } = request.params;
// Validate recordId format (e.g., UUID or numeric)
if (!/^[a-f0-9-]{36}$/.test(recordId)) {
throw Boom.badRequest('Invalid record identifier');
}
const docRef = firestore.doc(`tenants/${tenantId}/records/${recordId}`);
const doc = await docRef.get();
return doc.data();
}
});
When querying subcollections, avoid building paths from unchecked input. Instead, scope queries to the authenticated tenant or known safe prefixes:
// Secured subcollection query
const userOrdersRef = firestore
.doc(`users/${authenticatedUserId}`)
.collection('orders');
const snapshot = await userOrdersRef.get();
const orders = snapshot.docs.map(d => d.data());
return orders;
These practices reduce the risk of Path Traversal by ensuring that Firestore document references remain within expected boundaries. middleBrick’s Pro plan supports continuous monitoring to detect regressions in endpoint behavior, and its GitHub Action can enforce security thresholds in CI/CD pipelines.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |