147
High
Common Consequences
Scope Impact Likelihood
Integrity
Confidentiality
Availability
Execute Unauthorized Code or Commands
If a malicious user injects a character (such as a semicolon)
that delimits the end of one command and the
beginning of another, it may be possible to then insert an
entirely new and unrelated command that was not intended
to be executed.
Detection Methods
Automated Static Analysis
Automated static analysis, commonly referred to as Static Application Security Testing (SAST),
can find some instances of this weakness by analyzing source code (or binary/compiled code)
without having to execute it. Typically, this is done by building a model of data flow and control
flow, then searching for potentially-vulnerable patterns that connect "sources" (origins of input)
with "sinks" (destinations where the data interacts with external components, a lower layer such
as the OS, etc.)
Effectiveness = High
Potential Mitigations
Phase: Architecture and Design
If at all possible, use library calls rather than external processes to recreate the desired
functionality.
Phase: Implementation
If possible, ensure that all external commands called from the program are statically created.
Phase: Implementation
Strategy = Input Validation
Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use
a list of acceptable inputs that strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that does. When performing
input validation, consider all potentially relevant properties, including length, type of input, the
full range of acceptable values, missing or extra inputs, syntax, consistency across related
fields, and conformance to business rules. As an example of business rule logic, "boat" may be
syntactically valid because it only contains alphanumeric characters, but it is not valid if the input
is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for
malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if
the code's environment changes. This can give attackers enough room to bypass the intended
validation. However, denylists can be useful for detecting potential attacks or determining which
inputs are so malformed that they should be rejected outright.
Phase: Operation
Run time: Run time policy enforcement may be used in an allowlist fashion to prevent use of any
non-sanctioned commands.
Phase: System Configuration
Assign permissions that prevent the user from accessing/opening privileged files.
Demonstrative Examples
Example 1:
CWE Version 4.14
CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')
CWE-77: Improper Neutralization of Special
Elements used in a Command ('Command Injection') 148
The following simple program accepts a filename as a command line argument and displays the
contents of the file back to the user. The program is installed setuid root because it is intended for
use as a learning tool to allow system administrators in-training to inspect privileged system files
without giving them the ability to modify them or damage the system.
Example Language: C (Bad)
int main(int argc, char** argv) {
char cmd[CMD_MAX] = "/usr/bin/cat ";
strcat(cmd, argv[1]);
system(cmd);
}
Because the program runs with root privileges, the call to system() also executes with root
privileges. If a user specifies a standard filename, the call works as expected. However, if an
attacker passes a string of the form ";rm -rf /", then the call to system() fails to execute cat due to a
lack of arguments and then plows on to recursively delete the contents of the root partition.
Note that if argv[1] is a very long argument, then this issue might also be subject to a buffer
overflow (CWE-120).
Example 2:
The following code is from an administrative web application designed to allow users to kick
off a backup of an Oracle database using a batch-file wrapper around the rman utility and then
run a cleanup.bat script to delete some temporary files. The script rmanDB.bat accepts a single
command line parameter, which specifies what type of backup to perform. Because access to the
database is restricted, the application runs the backup as a privileged user.
Example Language: Java (Bad)
...
String btype = request.getParameter("backuptype");
String cmd = new String("cmd.exe /K \"
c:\\util\\rmanDB.bat "
+btype+
"&&c:\\utl\\cleanup.bat\"")
System.Runtime.getRuntime().exec(cmd);
...
The problem here is that the program does not do any validation on the backuptype parameter
read from the user. Typically the Runtime.exec() function will not execute multiple commands,
but in this case the program first runs the cmd.exe shell in order to run multiple commands with a
single call to Runtime.exec(). Once the shell is invoked, it will happily execute multiple commands
separated by two ampersands. If an attacker passes a string of the form "& del c:\\dbms\\*.*", then
the application will execute this command along with the others specified by the program. Because
of the nature of the application, it runs with the privileges necessary to interact with the database,
which means whatever command the attacker injects will run with those privileges as well.
Example 3:
The following code from a system utility uses the system property APPHOME to determine the
directory in which it is installed and then executes an initialization script based on a relative path
from the specified directory.
Example Language: Java (Bad)
...
String home = System.getProperty("APPHOME");
String cmd = home + INITCMD;
java.lang.Runtime.getRuntime().exec(cmd);
...
CWE Version 4.14
CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')
CWE-77: Improper Neutralization of Special
Elements used in a Command ('Command Injection')