You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Campione 1996 suggests:

To maximize portability, never refer to an environment variable when the same value is available in a system property. For example, if the operating system provides a user name, it will always be available in the system property user.name.

In fact, relying on environment variables is more than a simple portability issue. An attacker can essentially control all environment variables that enter a program, using a mechanism such as the java.lang.ProcessBuilder class.

Therefore, if an environment variable contains information that is available by other means, including system properties, that environment variable must not be used.

Noncompliant Code Example

This noncompliant code example tries to get the user name, using an environment variable.

String username = System.getenv("USER");

This certainly is a portability issue. Campione 1996 further suggests:

The way environment variables are used also varies. For example, Windows provides the user name in an environment variable called USERNAME, while UNIX implementations might provide the user name in USER, LOGNAME, or both.

Furthermore, an attacker can execute this program with the USER environment variable set to any value he chooses. The following code example does just that:

public static void main(String args[]) {
  if (args.length != 1) {
    System.err.println("Please supply a username as the argument");
    return;
  }
  String user = args[0];
  ProcessBuilder pb = new ProcessBuilder();
  pb.command("/usr/bin/printenv");
  Map<String,String> environment = pb.environment();
  environment.put("USER", user);
  pb.redirectErrorStream(true);
  try {
    Process process = pb.start();
    InputStream in = process.getInputStream();
    int c;
    while ((c = in.read()) != -1) {
      System.out.print((char) c);
    }
    int exitVal = process.waitFor();
  } catch (IOException x) {
    x.printStackTrace(System.err);
  } catch (InterruptedException x) {
    x.printStackTrace(System.err);
  }
}

This program runs the program /usr/bin/printenv which prints out all environment variables and their values. It takes a single argument string, and sets the USER environment variable to that string. The subsequent output of the printenv program will indicate that the USER environment variable is indeed set to the string requested.

Compliant Solution

This compliant solution obtains the user name using the user.name system property. This property always contains the correct user name, even if the USER environment variable has been set to an incorrect value, or does not exist.

String username = System.getProperty("user.name");

Risk Assessment

A program that depends on environment variables may be fed misinformation by an attacker.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

ENV02-J

low

likely

low

P9

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="7ca98214-3001-42fa-bee6-78458c2d9ffa"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="621fdb4f-277a-4856-b867-6bfff8566284"><ac:plain-text-body><![CDATA[

[[Campione 1996

AA. Bibliography#Campione 96]]

 

]]></ac:plain-text-body></ac:structured-macro>


void ENV05-J. Do not grant RuntimePermission with target createClassLoader      15. Runtime Environment (ENV)      ENV07-J. Do not deploy an application that can be accessed using the Java Platform Debugger Architecture

  • No labels