zenet_logo

-株式会社ゼネット技術ブログ-

JavaでできるSQLインジェクション対策法

初めまして。ゼネット新人の佐藤です。

現在私はJava、JDBC、PostgreSQLを使ったWEBアプリケーション研修をしています。

その際にSQLインジェクションの脆弱性がある危険なコードを書いてしまったことがあります。

 

そのため、今回は知らず知らずのうちに危険なコーディングをしないように、JavaでできるSQLインジェクションの対策方法について解説していこうと思います。

 

 

PreparedStatementの使用

JavaでできるSQLインジェクション対策の一つに、PreparedStatementのプレースホルダを使用したエスケープ処理が挙げられます。

プレースホルダとは?

後から実際に扱う値を入れる前に、一時的に場所を確保するために入れられる仮の値のこと。

エスケープ処理とは?

特別な意味を持つ文字列を、無害な別の文字列に変換すること。

 

PreparedStatementを使用した対策例

例えば、ユーザーがWEBページの入力フォームにデータを入力し、その入力データもとにSQLを実行するコードがあるとします。

この入力フォームに悪意のあるユーザーが不正なSQL文を入力した場合でも、以下の例のようにPreparedStatementを用いて対策したコードであれば、入力されたSQL文が無害化され、SQLインジェクションの対策が可能です。

 

入力フォームに入力された悪意のあるSQL文の例

101; DROP TABLE テーブル名;

 

PreparedStatementを使用したJavaコードの例

//実行されるSQL文、プレースホルダ「?」を設定
String sql = "SELECT * FROM テーブル名 WHERE  id = ?"
//入力された文字列
String str = "101; DROP TABLE テーブル名;";

//JDBCドライバの読み込み
Class.forName("org.postgresql.Driver");

//データベースへアクセスし接続情報を取得する
Connection connection = DriverManager.getConnection(DBのURL, ユーザID, パスワード);

//実行したいSQLからPreparedStatement型のSQL文を取得する
PreparedStatement pstatement = connection.prepareStatement(sql );
//「?」の部分に、String型の値にエスケープ処理した入力データを設定
pstatement.setString(1, str);

//SQL文の実行
pstatement.executeQuery();

 

上記のコードでは実行するSQL文にプレースホルダ「?」を設定しています

PreparedStatementインターフェースのメソッドsetString()を使用し、入力データをエスケープ処理してからプレースホルダと置き換えることで、不正な入力データを無害化し、SQLインジェクションの対策が可能となります。

 

上記の対策を行った場合には、実行されるSQL文は以下のようになり、入力データが文字列として扱われ、SQL文として実行されることはなくなります。

SELECT * FROM テーブル名 WHERE  id = '101; DROP TABLE テーブル名;'

 

仮にエスケープ処理を行わず、入力データを直接設定した場合には以下のようにSQL文が実行され、テーブルが削除される危険性があります。

SELECT * FROM テーブル名 WHERE  id = 101;
DROP TABLE テーブル名;

 

まとめ

SQLインジェクションの仕組みと対策法を知らないと、意図せず脆弱性のあるコードを書いてしまう可能性があります。

ユーザーの入力値をもとにSQL文を実行するコードを書く際はSQLインジェクションの対策を忘れないようにしましょう。

 

最後までお読みいただきありがとうございました。少しでも参考になれば幸いです。