> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semgrep.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Prevent Command Injection for Java

This is a command injection prevention cheat sheet by Semgrep, Inc. It contains code patterns of potential ways to run an OS command in an application. Instead of scrutinizing code for exploitable vulnerabilities, the recommendations in this cheat sheet pave a safe road for developers that mitigate the possibility of command injection in your code. By following these recommendations, you can be reasonably sure your code is free of command injection.

Learn more about [Command Injection](/learn/vulnerabilities/command-injection) vulnerability concepts.

### Check your project using Semgrep

```bash theme={null}
semgrep --config auto .
```

## 1. Running an OS command

### 1.A. Running OS commands with Runtime.getRuntime().exec()

The `exec` call executes the specified string command in a separate process. This is dangerous if a command string is controlled by user input and could result in command injection.

Example:

```java theme={null}
 // exec example
Runtime.getRuntime().exec("ls -la")

// Vulnerable
String input = "&& cat /etc/passwd"; // value supplied by user input
Runtime r = Runtime.getRuntime();
r.exec("some_tool -t param1 param2 " + input);

// Vulnerable
String input = "cat /etc/passwd"; // value supplied by user input
Runtime.getRuntime().exec("bash", "-c", input);
```

#### References

* [`exec` documentation](https://docs.oracle.com/javase/7/api/java/lang/Runtime.html#exec\(java.lang.String\))

#### Mitigation

* Always try to use internal Java API (if it exists) instead of running an OS command. In other words, use internal language features instead of invoking commands that can be exploited.
* Do not include command arguments in a command string, use parameterization instead. For example:<br />
  Use:
  ```java theme={null}
  Runtime.getRuntime().exec("/path/to/myCommand", "myArg1", inputValue)
  ```
  Instead of:
  ```java theme={null}
  Runtime.getRuntime().exec("bash", "-c", "myCommand myArg1 " + inputValue)
  ```
* If it is not possible, then strip the input of everything except alphanumeric characters provided for the command string and arguments.
* Do **not** use direct user input, even if it is sanitized.
* If it is not possible to avoid direct user input, do not allow running arbitrary commands. Use an allowlist for inputs.
* Strip `!@#$;&*~"'{}][-+%^` characters from user input that is incorporated in the command string which is later executed.

#### Semgrep rule

[`java.lang.security.audit.command-injection-formatted-runtime-call.command-injection-formatted-runtime-call`](https://semgrep.dev/r/java.lang.security.audit.command-injection-formatted-runtime-call.command-injection-formatted-runtime-call)

### 1.B. Running OS processes with ProcessBuilder

The `ProcessBuilder` class is used to create operating system processes. If the command string is controlled by user input it can result in command injection.
Example:

```java theme={null}
 // ProcessBuilder example
Process builder = new ProcessBuilder("ls", "-la").start();

// Vulnerable
String input = "cat /etc/passwd"; // value supplied by user input
ProcessBuilder builder = new ProcessBuilder();
builder.command("bash", "-c", "some_tool -t param1 param2 " + input)

// Vulnerable
String input = "cat /etc/passwd"; // value supplied by user input
ProcessBuilder builder = new ProcessBuilder();
builder.command(input);
```

#### References

[`ProcessBuilder` documentation](https://docs.oracle.com/javase/7/api/java/lang/ProcessBuilder.html)

#### Mitigation

* Try to avoid non-literal values in the command string.
* If it is not possible to prevent non-literal values in the command string, then do not allow running arbitrary commands. Use an allowlist for inputs.
* Do not include command arguments in a command string, use parameterization instead. For example:<br />
  Use:
  ```java theme={null}
  new ProcessBuilder("/path/to/myCommand", "myArg1", inputValue);
  ```
  Instead of:
  ```java theme={null}
  new ProcessBuilder("bash", "-c", "myCommand myArg1 " + inputValue);
  ```

#### Semgrep rule

[`java.lang.security.audit.command-injection-process-builder.command-injection-process-builder`](https://semgrep.dev/r/java.lang.security.audit.command-injection-process-builder.command-injection-process-builder)
