Server Side Template Injection in Firestore
How Server Side Template Injection Manifests in Firestore
Server Side Template Injection (SSTI) in Firestore occurs when untrusted data is directly embedded into Firestore queries or configuration objects without proper sanitization. Unlike traditional SSTI in web templates, Firestore-specific SSTI manifests through query construction and document field manipulation.
The most common Firestore SSTI pattern involves dynamically constructing queries using user input:
// Vulnerable code - direct interpolation of user input
const collection = req.query.collection;
const docId = req.query.docId;
const userQuery = db.collection(collection).doc(docId).get();
This allows attackers to manipulate collection names, document paths, or field names. For example, an attacker could supply collection=users/./admin to traverse directories or use special characters to access unintended data.
Firestore's flexible schema makes it particularly vulnerable to field-level SSTI:
// Vulnerable field injection
const fieldName = req.query.field;
const value = req.query.value;
const query = db.collection('users').where(fieldName, '==', value);
An attacker could supply field=$key or use Firestore's reserved field names to manipulate query behavior. The $key field, for instance, allows access to document IDs, potentially exposing data across collections.
Another critical vector is document ID manipulation:
// Vulnerable document ID construction
const userId = req.params.userId;
const userDoc = db.collection('users').doc(userId);
Attackers can craft document IDs that traverse collection hierarchies or access system collections. Firestore's document ID format accepts slashes, allowing path traversal attacks like users/../config.
Firestore's FieldValue methods present unique SSTI opportunities:
// Vulnerable FieldValue injection
const incrementValue = req.query.increment;
const increment = parseInt(incrementValue) || FieldValue.increment(1);
If input validation is bypassed, attackers could inject malicious FieldValue objects, potentially causing data corruption or unauthorized modifications.
Batch operations amplify SSTI risks:
// Vulnerable batch operation
const batch = db.batch();
batch.update(db.collection('users').doc(req.query.id), {
[req.query.field]: req.query.value
});
Batch operations execute atomically, making them attractive targets for attackers seeking to modify multiple documents simultaneously through crafted input.
Firestore-Specific Detection
Detecting SSTI in Firestore requires both static analysis and runtime monitoring. The most effective approach combines automated scanning with manual code review.
Static analysis should focus on query construction patterns:
const vulnerablePatterns = [
/db\.collection\(.*\)\.doc\(.*\)/g, // Direct doc() calls
/where\(.*\)/g, // Dynamic where clauses
/update\(.*\)/g, // Dynamic field updates
/FieldValue\./g // FieldValue usage
];
Look for code that dynamically constructs collection names, document IDs, or field names using user input. Pay special attention to eval(), Function(), or JSON.parse() usage with untrusted data.
Runtime detection involves monitoring query patterns:
// Runtime monitoring middleware
const suspiciousQueries = [];
const monitorQueries = (query) => {
if (///.test(query.path)) {
suspiciousQueries.push({ type: 'path_traversal', query });
}
if (query.field.includes('$')) {
suspiciousQueries.push({ type: 'reserved_field', query });
}
};
Implement query logging to detect unusual patterns like repeated access to system collections (_FIREBASE, _analytics) or excessive document reads from administrative collections.
middleBrick's automated scanning specifically targets Firestore SSTI vectors:
Authentication Bypass Testing - Attempts to access collections without proper authentication, testing if document-level security is properly enforced.
Property Authorization Testing - Probes for unauthorized field access by attempting to read/write system-reserved fields like createdAt, updatedAt, or $key.
Input Validation Testing - Tests how the API handles special characters, path traversal sequences, and reserved keywords in collection names, document IDs, and field names.
Data Exposure Testing - Attempts to access documents across collection boundaries using crafted document IDs and field names.
The scanning process takes 5-15 seconds and provides a security score with specific findings. For Firestore APIs, middleBrick tests 12 security categories including the Firestore-specific vectors mentioned above.
Firestore-Specific Remediation
Remediating SSTI in Firestore requires a defense-in-depth approach combining input validation, query whitelisting, and proper security rules.
Input validation should be strict and whitelist-based:
// Whitelist validation for collection names
const VALID_COLLECTIONS = ['users', 'posts', 'comments'];
function validateCollectionName(name) {
if (!VALID_COLLECTIONS.includes(name)) {
throw new Error('Invalid collection name');
}
return name;
}
function validateDocumentId(id) {
// Only alphanumeric and underscores
if (!/^[a-zA-Z0-9_]+$/.test(id)) {
throw new Error('Invalid document ID');
}
return id;
}
function validateFieldName(name) {
// Disallow reserved fields and special characters
const reservedFields = ['$key', 'createdAt', 'updatedAt'];
if (reservedFields.includes(name) || /[^a-zA-Z0-9_]/.test(name)) {
throw new Error('Invalid field name');
}
return name;
}
Query whitelisting prevents dynamic query construction:
// Query builder with whitelist
const VALID_QUERIES = {
users: {
byEmail: (email) => db.collection('users').where('email', '==', email),
byId: (id) => db.collection('users').doc(id),
},
posts: {
byAuthor: (authorId) => db.collection('posts')
.where('authorId', '==', authorId),
}
};
function safeQuery(collection, operation, params) {
if (!VALID_QUERIES[collection] || !VALID_QUERIES[collection][operation]) {
throw new Error('Invalid query');
}
return VALID_QUERIES[collection][operation](...params);
}
Firestore security rules provide the final defense layer:
Implement comprehensive logging for all database operations:
// Operation logging
const operationLog = [];
function logOperation(type, collection, docId, fields) {
operationLog.push({
timestamp: Date.now(),
type,
collection,
docId,
fields,
user: auth.currentUser?.uid
});
// Alert on suspicious patterns
if (///.test(docId)) {
console.warn('Potential path traversal detected', { docId });
}
}
Regular security audits should include:
- Static code analysis for dynamic query construction
- Runtime monitoring of query patterns
- Security rule validation
- Penetration testing of API endpoints
middleBrick's continuous monitoring (Pro plan) can automatically scan your Firestore APIs on a configurable schedule, alerting you to new SSTI vulnerabilities as they emerge.
Frequently Asked Questions
Can SSTI in Firestore lead to data exfiltration?
Yes, SSTI in Firestore can enable data exfiltration through several mechanisms. Attackers can craft document IDs to traverse collection hierarchies and access administrative collections. They can also manipulate field names to read system-reserved fields containing sensitive metadata. Additionally, SSTI can bypass query filters, allowing attackers to read all documents in a collection rather than just their own. The flexible schema of Firestore makes it particularly vulnerable to field-level injection attacks where attackers can read fields they shouldn't have access to by manipulating query construction.
How does middleBrick detect Firestore SSTI vulnerabilities?
middleBrick detects Firestore SSTI through black-box scanning that tests unauthenticated attack surfaces. The scanner attempts to manipulate collection names, document IDs, and field names using special characters, path traversal sequences, and reserved keywords. It tests for unauthorized access to system collections and attempts to bypass document-level security. The scanning process takes 5-15 seconds and provides a security score with specific findings for each vulnerability category. For Firestore APIs, middleBrick tests 12 security categories including authentication bypass, property authorization, and input validation - all critical for detecting SSTI vulnerabilities.