Injection Attacks
Injection attacks are a class of vulnerabilities where an attacker sends untrusted data to an interpreter as part of a command or query, causing unintended execution of the attacker's instructions.
Understanding Injection Attacks
Injection attacks all share the same fundamental flaw: mixing data with instructions. When user input is concatenated into a command string and sent to an interpreter (SQL engine, operating system shell, LDAP directory, template engine), the attacker can break out of the data context and inject their own commands.
Beyond SQL injection, important injection types include OS command injection (executing shell commands through functions like exec() or system()), LDAP injection (manipulating LDAP queries used for authentication and directory lookups), server-side template injection (SSTI — injecting code into template engines like Jinja2, Handlebars, or EJS), NoSQL injection (manipulating MongoDB queries through JSON operator injection), and header injection (injecting newlines into HTTP headers to add custom headers or split responses).
OS command injection is particularly devastating because it provides direct access to the server's operating system. If an application passes user input to a shell command (e.g., calling imagemagick or ffmpeg with user-provided filenames), an attacker can append shell operators (;, |, &&) to execute arbitrary commands.
The universal defense is separation of data from instructions. For SQL, use parameterized queries. For OS commands, use APIs that accept arguments as arrays rather than shell strings. For templates, use engines that sandbox user input. For LDAP, use parameterized filters. When separation is not possible, apply strict allowlist validation on the input.
Why This Matters for Vibe-Coded Apps
AI-generated code is susceptible to multiple injection types beyond SQL. When AI builds features that shell out to command-line tools (image processing, PDF generation, file conversion), it often constructs command strings with string interpolation, creating command injection vulnerabilities. Similarly, AI may generate server-side templates that evaluate user input as code.
Review AI-generated code for any place where user input flows into exec(), spawn(), system(), eval(), or template rendering functions. For shell commands, use the child_process.execFile function with arguments as an array instead of child_process.exec with a concatenated string. For templates, ensure user input is treated as data, not code.
Real-World Examples
Equifax Command Injection (2017)
The massive Equifax breach that exposed 147 million people's data began with a command injection vulnerability in Apache Struts (CVE-2017-5638). The exploit allowed remote code execution through a crafted Content-Type header, demonstrating how a single injection point can lead to a catastrophic breach.
Shellshock (CVE-2014-6271)
The Shellshock vulnerability in Bash allowed command injection through environment variables. Web servers using CGI scripts were particularly vulnerable — HTTP headers were passed as environment variables to Bash, allowing attackers to inject commands through headers like User-Agent.
Uber SSTI Vulnerability (2016)
A server-side template injection in Uber's Jinja2 templates allowed remote code execution. By injecting template syntax into a parameter that was rendered in a Jinja2 template, the researcher could execute arbitrary Python code on Uber's servers.
Frequently Asked Questions
What is the most dangerous type of injection attack?
OS command injection is typically the most dangerous because it provides direct access to the server's operating system. An attacker can read files, install malware, pivot to other systems on the network, and establish persistent access. SQL injection with database admin privileges is similarly dangerous as it can enable file system access and command execution through database features like xp_cmdshell (MSSQL) or COPY TO PROGRAM (PostgreSQL).
How do I prevent command injection in Node.js?
Use child_process.execFile() or child_process.spawn() instead of child_process.exec(). The exec function passes the entire command to a shell, enabling injection through shell operators. execFile and spawn take the command and arguments as separate parameters, preventing the arguments from being interpreted as shell commands. Additionally, validate all user input against an allowlist before using it in any command context.
What is server-side template injection?
SSTI occurs when user input is embedded in a server-side template and evaluated by the template engine. Template engines like Jinja2, EJS, and Handlebars execute code within special delimiters ({{ }}, <% %>, etc.). If user input reaches the template without escaping, attackers can inject template directives that execute arbitrary code on the server. The fix is to never include user input in template source code — use the template's data binding to pass user input as variables.
Is eval() always dangerous?
Yes, in any context where user input can reach it. eval() executes a string as code, making it a direct injection vector. Even indirect eval (new Function(), setTimeout with a string argument) carries the same risk. There are rare legitimate uses of eval (code playgrounds, dynamic code loading) but these must never process user input. In most applications, there is no valid reason to use eval. ESLint rules like no-eval exist specifically to catch this dangerous pattern.
Is Your App Protected?
VAS automatically scans for vulnerabilities related to injection attacks and provides detailed remediation guidance. Our scanner targets issues common in AI-generated applications.
Scans from $5, results in minutes. Get actionable fixes tailored to your stack.
Get Starter Scan