Command Injection in Feathersjs with Firestore
Command Injection in Feathersjs with Firestore β how this specific combination creates or exposes the vulnerability
Command Injection occurs when an attacker can inject and execute arbitrary system commands through an application. In a Feathersjs application that uses Firestore, the risk typically arises not from Firestore itself, which is a managed NoSQL database, but from unsafe handling of data that originates from client-supplied inputs and is later used in system-level operations. If Feathersjs services accept user input and pass it to functions that execute shell commands or interact with the host system, the combination can expose a command injection surface.
Feathersjs is a framework for building JavaScript APIs with hooks and services. Firestore is often used as a data store via adapters or direct SDK usage. The vulnerability emerges when developer code takes parameters from Firestore documents or query results and forwards them to utilities such as exec, spawn, or child_process. For example, if a Firestore document contains a field that is later used in a shell command without proper validation or escaping, an attacker who can manipulate that document (for instance, through compromised credentials or a secondary injection vector) may be able to influence the command executed by the server.
Another scenario involves build or deployment scripts that interact with Firestore and also invoke shell commands. If these scripts embed Firestore data directly into command strings, the boundary between data and command language breaks down. This is not a flaw in Feathersjs or Firestore per se, but a result of insecure coding practices where input from one system component is treated as safe for another system boundary. The scanner checks for indicators of such patterns, including the presence of command-execution functions combined with dynamic input that may originate from external sources, including data retrieved from databases like Firestore.
Additionally, if an API endpoint returns configuration or metadata stored in Firestore and that data is used by an external process or orchestration tool to construct commands, the API can act as a conduit for injection. The scanner examines endpoints for input validation weaknesses and traces how data flows from the request, through services, and potentially into system-level execution contexts. Even though Firestore does not directly execute shell commands, its role as a data source means that improperly sanitized values can contribute to a command injection chain when consumed by other parts of the infrastructure.
Firestore-Specific Remediation in Feathersjs β concrete code fixes
Remediation focuses on ensuring that data from Firestore is never directly interpolated into system commands. Use parameterized commands, strict input validation, and separation of data from control logic. Below are concrete code examples that demonstrate secure patterns in a Feathersjs service using the Firestore SDK.
First, avoid using dynamic data in shell commands. If you must run system commands, use a controlled set of pre-approved operations and pass data only through strictly validated and sanitized inputs. For instance, instead of building a command string with user data, use a mapping approach that selects from a fixed set of allowed values:
const { Service } = require('feathersjs');
const { execFile } = require('child_process');
const { promisify } = require('util');
const execFileAsync = promisify(execFile);
class SecureFileOperationService extends Service {
async create(data, params) {
// Assume data.type comes from validated client input, not directly from Firestore
const allowedTypes = {
'pdf': 'generate-pdf',
'csv': 'export-csv'
};
const command = allowedTypes[data.type];
if (!command) {
throw new Error('Invalid operation type');
}
// Pass arguments as an array to execFile; data values come from a trusted source
const { stdout, stderr } = await execFileAsync(command, ['--output', '/tmp/report.out']);
return { stdout, stderr };
}
}
Second, when working with Firestore data, explicitly validate and sanitize any fields that could reach system-level operations. For example, if a Firestore document contains a filename or path, ensure it conforms to an expected pattern and resides within an allowed directory:
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
async function getDocumentAndOperate(id) {
const doc = await db.collection('jobs').doc(id).get();
if (!doc.exists) {
throw new Error('Document not found');
}
const data = doc.data();
// Validate filename format before any further use
const filename = data.filename;
if (!/^[a-zA-Z0-9._-]+$/.test(filename)) {
throw new Error('Invalid filename');
}
const safePath = `/safe/base/dir/${filename}`;
// Use safePath in controlled operations; do not embed raw user input
console.log(`Processing ${safePath}`);
}
Third, in deployment or CI/CD contexts where Feathersjs tools may read Firestore configuration to construct commands, ensure that configuration values are static and do not contain executable templates. Prefer environment variables for runtime configuration and keep Firestore as a data store rather than a command template engine.
| Insecure Pattern | Why Itβs Risky | Secure Alternative |
|---|---|---|
exec('convert ' + firestoreData.input + ' ' + firestoreData.output) |
User-controlled strings are concatenated into a shell command, enabling command injection if the data is malicious. | execFile('convert', ['input.txt', 'output.png']) with validated, non-shell arguments. |
child_process.execSync(`gsutil cp ${firestoreData.path} gs://bucket/`) |
Template literals embed data directly into the command string, bypassing shell escaping. | Use library functions with argument arrays and validate firestoreData.path against a whitelist. |
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 |