SV.EXEC
プロセス挿入
このエラーは、アプリケーションによって実行されるオペレーティングシステムコマンドのすべてまたは一部に対し、ユーザー入力が未チェックで使用される場合に検出されます。
リリース 2023.2 の時点で、このチェッカーは Jakarta EE をサポートしています。
リリース 2026.3 以降、このチェッカーは LLM 応答テキストも信頼できないソースとして扱います。
脆弱性とリスク
一般に、アプリケーション内での外部コマンドのプロセス作成や実行は、セキュリティ上の懸念事項となります。実行に使用されるコマンド文字列の一部にユーザー入力が使用される場合には、重大な脆弱性があります。攻撃者は、追加コマンドを挿入し、それらをアプリケーションサーバー上で実行することにより、プロセスまたはコマンドインジェクションの状態を引き起こすことができます。任意のコマンドを実行可能であるため、サービス拒否 (DoS)、データ破損、データのセキュリティ違反などの危険性があります。
Klocwork セキュリティ脆弱性 (SV) チェッカーは、潜在的に危険なデータを生成する呼び出しを特定します。このような呼び出しは安全でないソースと考えられます。ユーザーは攻撃者になる可能性があり、ヒューマンエラーを取り込む可能性があるため、安全でないソースはユーザーが指定した任意のデータである可能性があります。
軽減と防止
プロセス攻撃やコマンドインジェクション攻撃は、アプリケーションの外部からのあらゆる入力 (ユーザー入力、ファイル入力、システムパラメーターなど) を検証することで防止できます。検証には、長さと内容を含める必要があります。理想としては、ユーザーデータをプロセス作成コマンドで使用することは避ける必要があります。受け取ったその他の文字はすべてエスケープする必要があります。検証はデータのソースごとに実行します。たとえば、各パラメーターを HTTP 要求やユーザーインターフェイス (アプリケーション、コンソールなど) から読み取った場合に実行します。
脆弱コード例 1
import javax.servlet.*;
public void checkHost(ServletRequest req) throws IOException {
// Source of data from HTTP request in servlet
String hostName = req.getParameter("userHostName");
String command = "nslookup " + hostName;
Process proc = Runtime.getRuntime().exec(command);
// ...
}
Klocwork は、6 行目で SV.EXEC の欠陥を報告し、次を示します。'hostName' には HTTP 要求パラメーターからのデータが含まれているため、汚染される可能性があります (4 行目)。この値は定数文字列と連結され、5 行目で 'command' に保存されます。'command' は 6 行目でシェルコマンドとして実行されるため、ホストシステムは、攻撃者によって実行される危険なコマンドに対して脆弱です。
脆弱コード例 2
import jakarta.servlet.*;
public void checkHost(ServletRequest req) throws IOException {
// Source of data from HTTP request in servlet
String hostName = req.getParameter("userHostName");
String command = "nslookup " + hostName;
Process proc = Runtime.getRuntime().exec(command);
// ...
}
Klocwork は、6 行目で SV.EXEC の欠陥を報告し、次を示します。'hostName' には HTTP 要求パラメーターからのデータが含まれているため、汚染される可能性があります (4 行目)。この値は定数文字列と連結され、5 行目で 'command' に保存されます。'command' は 6 行目でシェルコマンドとして実行されるため、ホストシステムは、攻撃者によって実行される危険なコマンドに対して脆弱です。
脆弱コード例 3
import dev.langchain4j.model.chat.ChatModel;
import java.io.IOException;
public class Example {
public void run(ChatModel model) throws IOException {
String command = model.chat("What command fixes the disk?"); // untrusted LLM output
Runtime.getRuntime().exec(command); // model output run as a process
}
}
信頼できない LLM 出力がオペレーティングシステムのコマンドとして直接実行されているため、Klocwork は 6 行目で SV.EXEC の欠陥を報告しています。
修正コード例 3
import dev.langchain4j.model.chat.ChatModel;
import java.io.IOException;
import java.util.Map;
public class Example {
private static final Map<String, String> ALLOWED =
Map.of("restart", "/usr/bin/systemctl restart app", "status", "/usr/bin/systemctl status app");
public void run(ChatModel model) throws IOException {
String action = model.chat("restart or status?");
String command = ALLOWED.get(action); // map to a fixed allow-list; reject anything else
if (command != null) {
Runtime.getRuntime().exec(command);
}
}
}
この修正例では、モデルの出力が直接実行されるのではなく、固定の許可リストにマッピングされるため、Klocwork は SV.EXEC の欠陥を報告しなくなります。
外部参考資料
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、Java 解析のチューニングを参照してください。