SV.SQL
SQL インジェクション
このエラーは、未検証データや汚染データが SQL クエリ文字列に直接使用されている状況を示します。具体的には、J2EE サーブレット経由の HTTP 要求など、さまざまなソースからのユーザー入力がトレースされ、このデータが SQL 文で使用されることが検出されます。java.sql.Statement.execute() メソッドで使用される SQL 文にこのデータが未チェックのまま直接使用される場合、攻撃者によって任意の SQL 文がこの文字列に入力される可能性があります。その場合、ユーザーインターフェイスから任意の SQL コマンドが直接実行可能になります。
リリース 2023.2 の時点で、このチェッカーは Jakarta EE をサポートしています。
脆弱性とリスク
SQL インジェクションは、データベースのデータを危険な状態にします。未検証のユーザー入力が SQL 文で使用されているため、攻撃者は実行しようとする任意の SQL 文を挿入できるようになります。これには、データの削除、更新、作成などが含まれます。また、この種の脆弱性があるデータベースから機密データが取得される可能性もあります。コマンドが認証に使用された場合には、不正アクセスが発生します。
Klocwork セキュリティ脆弱性 (SV) チェッカーは、潜在的に危険なデータを生成する呼び出しを特定します。このような呼び出しは安全でないソースと考えられます。ユーザーは攻撃者になる可能性があり、ヒューマンエラーを取り込む可能性があるため、安全でないソースはユーザーが指定した任意のデータである可能性があります。
軽減と防止
SQL インジェクション攻撃は、アプリケーションの外部からのあらゆる入力 (ユーザー入力、ファイル入力、システムパラメーターなど) を検証することで防止できます。検証には、長さと内容を含める必要があります。通常、英数字文字 (A ~ Z、a ~ z、0 ~ 9) のみが必要とされます。受け取ったその他の文字はすべてエスケープする必要があります。この検証は、各パラメーターを HTTP 要求から読み取った場合などに、データのソースごとに実行する必要があります。また、SQL 文で使用されるすべての文字列を、その使用前にチェックすることが推奨されます。サンプルのような SQL 文の使用も危険です。これは、インジェクション攻撃やその他の潜在的に危険な SQL 文の実行を許可します。レコードの作成、更新、削除には、準備済み SQL 文を使用します。
脆弱例 1
import javax.servlet.http.*;
public ResultSet getUserData(ServletRequest req, Connection con) throws SQLException {
// Source of data from HTTP request in servlet
String accountNumber = req.getParameter("accountNumber");
// Use of string in SQL statement
String query = "SELECT * FROM user_data WHERE userid = '" + accountNumber + "'";
Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
return results;
}
Klocwork は、8 行目で SV.SQL の欠陥を報告し、次を示します。'accountNumber' には HTTP 要求パラメーターからのデータが含まれているため、汚染される可能性があります (4 行目)。この値は、6 行目で定数文字列と連結され、'query' が構成されます。'query' は、8 行目で SQL ステートメントとして実行されます。これは、任意の SQL 文のインジェクションに利用される可能性があります。
脆弱例 2
import jakarta.servlet.http.*;
public ResultSet getUserData(ServletRequest req, Connection con) throws SQLException {
// Source of data from HTTP request in servlet
String accountNumber = req.getParameter("accountNumber");
// Use of string in SQL statement
String query = "SELECT * FROM user_data WHERE userid = '" + accountNumber + "'";
Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
return results;
}
Klocwork は、8 行目で SV.SQL の欠陥を報告し、次を示します。'accountNumber' には HTTP 要求パラメーターからのデータが含まれているため、汚染される可能性があります (4 行目)。この値は、6 行目で定数文字列と連結され、'query' が構成されます。'query' は、8 行目で SQL ステートメントとして実行されます。これは、任意の SQL 文のインジェクションに利用される可能性があります。
外部参考資料
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、Java 解析のチューニングを参照してください。