SV.CODE_INJECTION.SHELL_EXEC
Command injection vulnerability
When the system() or popen() function is used with externally-influenced input, it's possible for a malicious user to inject a string and execute arbitrary commands and code with the privileges of the attacked process. For example, an attacker could inject a semi-colon to end one command and insert a new, unrelated command for execution.
Vulnerability and risk
A system() or popen() call that's vulnerable to command injection can result in
- execution of malicious code
- creation of a new user account to access a compromised system
- arbitrary command execution with a higher privilege level than the standard user
In a worst-case scenario, an attacker could inject a string that takes control of the system, and for instance, delete the contents of the root partition.
Mitigation and prevention
To avoid this issue, it's best to
- use only constant strings with a system call
- add validation code before command execution
- use library calls rather than external processes
- use whitelist rather than blacklist input validation
- use the exec family of functions to run external executables
- make sure any external executable can't be written by the user
- implement functionality directly in the program with calls to existing libraries
Vulnerable code example
char *constbuf = "bash";
int main()
{
char buf[100];
scanf("%s",buf);
system("echo \"constant string: no warning\"");
system(constbuf);
system(buf);
popen("echo OK","r");
popen(constbuf, "r");
popen(buf, "r");
return 0;
}
In this example, Klocwork produces an issue report at line 9 indicating that system() function may accept a command line that can be influenced by the user, causing the execution of arbitrary code. A similar warning is reported for function popen() at line 12. In either of these cases, an attacker could inject commands to execute malicious code, even to the extent of taking control of the system or deleting the root partition. The system function calls in lines 6 and 8 use a constant string and a library call as arguments, so they aren't open to the possibility of code injection and aren't flagged.
Related checkers
External guidance
- CERT ENV33-C: Do not call system()
- CWE-20: Improper Input Validation
- CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')
- CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
- CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')
- CWE-94: Improper Control of Generation of Code ('Code Injection')
- CWE-99: Improper Control of Resource Identifiers ('Resource Injection')
- CWE-400: Uncontrolled Resource Consumption
- OWASP A3:2021 Injection
- STIG-ID:APP3570 Application vulnerable to Command Injection
Security training
Application security training materials provided by Secure Code Warrior.