0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SQLインジェクション

Posted at

SQLインジェクションとは

アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと、また、その攻撃を可能とする脆弱性のことです。
SQLに別のSQL文を「注入(inject)」されることから、「ダイレクトSQLコマンドインジェクション」もしくは「SQL注入」とも呼ばれます。

アプリケーションが入力値を適切にエスケープしないままSQL中に展開することによりで発生します。

次のようなSQLが発行されることを前提に説明します。

SELECT * FROM users WHERE name = '(入力値)';

ここで入力値に "1' OR '1' = '1" という文字列を与えた場合を考えると、SQL文は次のように展開されます。

SELECT * FROM users WHERE name = '1' OR '1' = '1';

上記のSQL文では条件が常に真となるため、nameカラムの値にかかわらず、レコードが全件取得できてしまいます。このような攻撃は、入力値が1つだけのものに限りません。
また、これを応用してSELECTの条件式にデータベース内の情報を確認するようなサブクエリーを含ませ、その抽出の成否によって本来参照することのできないデータベース内の情報(テーブル名など)を知ることができる、ブラインドSQLインジェクションと呼ばれる手法も存在する。
また、複数のSQL文を注入することによるデータの破壊や改竄、ストアドプロシージャを実行させ、情報の漏洩や改竄、OSコマンドの実行などを引き起こすこが可能のる場合があります。

対策

  • 型を指定する
  • 静的プレースホルダの利用する
  • 発行するsql文の中で文字列展開をしない
  • 文字エンコーディングを指定する
  • 入力値に対してのチェックを行う

Javaでの静的プレースホルダ実装例

import java.sql.PreparedStatement;

public class Main {

    public static void main(String[] args) {
        /**
         * 省略
         */
        stmt = conn.prepareStatement("SELECT name, secret FROM users WHERE user = 'true' AND name = ? AND password = ? ");
        stmt.setString(1, name);
        stmt.setString(2, password);
        rs = stmt.executeQuery();
    }
}

0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?