SV.EXEC.LOCAL

Process Injection. Local Arguments.

This error is reported when application arguments are used, unchecked, for all or part of an operating system command executed by the application. This checker differs from other SV.EXEC checkers in that it targets “Local” parameters to the application, which require an attacker to have the ability to modify settings on the machine running the Java application.

Application arguments covered by this checker include: Command Line Arguments, Environment Variables or Java System Properties.

Vulnerability and risk

The application accepts an input that it uses to fully select which program to run, as well as which commands to use. The application simply redirects this entire command to the operating system.

The programmer does not intend for the command to be accessible to any untrusted party, but the programmer probably has not accounted for alternate ways in which malicious attackers can provide input.

Mitigation and prevention

Consider storing settings in properties files with known paths instead of using main arguments, system properties or environment variables. Secure properties files with appropriate permissions. Include properties in a signed jar or verify integrity of the file using a checksum.

Don’t invoke the shell through Runtime.exec() or ProcessBuilder().

The following is an example of reading settings from a ".properties" file:

Copy
   Properties props = 
   getClass().getClassLoader().getResourceAsStream("config.properties")
   String toolsHome = props.getProperty("tools.path")

Vulnerable code example 1

In this example, if an attacker gains control over the "TOOLS_PATH" environment variable, then they can modify the property to point to a dangerous program (located at "$TOOLS_PATH/bin/jmap").

Copy
   public static void generateHeapDump() {
       Long processId = getProcessId();
       String jmapPath = getJmapPath();
       String[] dumpCommands = new String[] {jmapCommand,
                                               "-dump:format=b,file=" + dumpPath,
                                               processId.toString()};
       try {
           Runtime.getRuntime().exec(dumpCommands);
       } catch (IOException e) {
          logger.error("The heap dump could not be generated due to the following error: ", e);
      }
  }
  
      
  private static String getJmapPath() {
      String toolsPath = System.getenv("TOOLS_PATH");
      if (toolsPath == null)
          return null;
      
      File binDirectory = new File(toolsPath, "bin");
      File[] files = binDirectory.listFiles(new FilenameFilter() {
          public boolean accept(File dir, String name) {
              return name.startsWith("jmap");
          }
      });
      
      return ArrayUtils.isEmpty(files) ? null : files[0].getPath();
  }

Vulnerable code example 2

The problem in this example is that the program does not perform any validation on the backuptype system property. 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 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 that whatever command the attacker injects will run with those privileges as well.

Copy
   ...
   String btype = System.getProperty("backuptype");
   String cmd = new String("cmd.exe /K \"
   c:\\util\\rmanDB.bat "
   +btype+
   "&&c:\\utl\\cleanup.bat\"")
   System.Runtime.getRuntime().exec(cmd);
   ...

Related checkers

Security training

Application security training materials provided by Secure Code Warrior.