Why is this an issue?
Environment variable injection occurs in an application when the application receives data from a user or a third-party service and, without
sanitizing it first, does the following:
A user with malicious intent carefully performs actions aimed at modifying or adding environment variables to profit from it.
What is the potential impact?
When user-supplied values are used to manipulate environment variables, an attacker can supply carefully chosen values that cause the system to
behave unexpectedly.
In some cases, the attacker can use this capability to execute arbitrary code on the server.
Below are some real-world scenarios that illustrate some impacts of an attacker exploiting the vulnerability.
Application-specific attacks
In this scenario, the attacker manages to inject an environment variable that is recognized and used by the remote system. For example, this could
be the secret of a particular cloud provider used in an environment variable, or PATH
.
Depending on the application, the attacker can read or modify important data or perform unwanted actions.
For example, injecting data into the
HTTP_PROXY
variable could lead to data leakage.
Application compromise
In the worst case, an attacker manages to inject an important environment variable such as ` LD _PRELOAD` and execute code by overriding trusted
code.
Depending on the attacker, code execution can be used with different intentions:
- Download the internal server’s data, most likely to sell it.
- Modify data, install malware, and for instance, malware that mines cryptocurrencies.
- Stop services or exhaust resources, for instance, with fork bombs.
This threat is particularly insidious if the attacked organization does not maintain a Disaster Recovery Plan (DRP).
How to fix it in Java SE
Code examples
The following code is vulnerable to environment variable manipulation as it constructs the variables from untrusted data.
Noncompliant code example
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Runtime r = Runtime.getRuntime();
String userInput = request.getParameter("example");
if (userInput != null) {
String[] envs = {userInput};
r.exec("/path/to/example", userInput);
} else{
r.exec("/path/to/example");
}
}
Compliant solution
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Runtime r = Runtime.getRuntime();
String userInput = request.getParameter("example");
if (userInput != null && userInput.matches("^[a-zA-Z0-9]*$")) {
String[] envs = {"ENV_VAR=%s".format(userInput)};
r.exec("/path/to/example", envs);
} else {
r.exec("/path/to/example");
}
}
How does this work?
User input should be properly sanitized and validated, and ideally used only for the value of the environment variable. The environment variable
name should be statically defined.
Validation and sanitization could be done by restricting alphanumeric characters for the value and evaluating the name, if not statically defined,
against an allowlist of name values.
Resources
Standards