SV.EXEC.LOCAL

プロセス インジェクション。ローカル引数。

このエラーは、アプリケーションによって実行されるオペレーティングシステムコマンドのすべてまたは一部に対し、アプリケーション引数が未チェックで使用される場合に報告されます。このチェッカーは他の SV.EXEC チェッカーとは異なり、アプリケーションに対する「ローカル」パラメーターをターゲットにします。これにより攻撃者は、Java アプリケーションを実行するマシンでの設定の変更が必要になります。

このチェッカーが対象とするアプリケーション引数には以下があります。コマンドライン引数、環境変数、または Java システムプロパティ。

脆弱性とリスク

アプリケーションは、それが使用する入力を受け入れ、実行するプログラムおよび使用するコマンドをフルに選択します。アプリケーションはコマンド全体を単に OS にリダイレクトするだけです。

プログラマーは信頼できないパーティーからコマンドへのアクセスを可能にするつもりはありません。おそらく、プログラマーは、悪意のある攻撃者が入力を提供できる代替の方法については考慮していないと思われます。

軽減と防止

メインの引数、システムプロパティ、または環境変数を使用する代わりに、既知のパスでプロパティファイルに設定を保存することを考慮します。適切なパーミッションでプロパティファイルの安全を確保します。プロパティを署名付き jar に含めるか、またはチェックサムを使用してファイルの整合性を検証します。

Runtime.exec() または ProcessBuilder() を介してシェルを呼び出さないようにします。

次の例は、「.properties」ファイルからの設定の読み取りを示しています。

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

脆弱コード例 1

この例では、攻撃者が TOOLS_PATH 環境変数に対する制御を取得した場合、このプロパティを変更して($TOOLS_PATH/bin/jmapにある)危険なプログラムをポイントすることが可能です。

コピー
   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();
  }

脆弱コード例 2

この例での問題は、プログラムが backuptype システムプロパティについて検証を実行しないことです。通常、Runtime.exec() 関数は複数のコマンドを実行しませんが、このケースではプログラムは、Runtime.exec() の 1 つの呼び出しによって複数のコマンドを実行するために、まず、cmd.exe シェルを実行します。シェルが呼び出されると、2 つのアンパサンドによって区切られた複数のコマンドを実行します。仮に攻撃者が「&& del c:\\dbms\\*.*」形式の文字列を渡した場合、アプリケーションは、プログラムによって指定されたその他のコマンドと一緒にこのコマンドを実行します。アプリケーションの性質上、アプリケーションはデータベースとの連携に必要な権限で実行します。つまり、攻撃者が挿入したコマンドもまた同様にこれらの権限で実行されることになります。

コピー
   ...
   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);
   ...

関連チェッカー