SQLインジェクションとは?

SQLインジェクションについて

まず、インジェクションとは日本語で「注入」を意味し、攻撃者がデータベースに不正な命令を注入することからこの名前が使われています。SQLインジェクションが起きた場合、不正ログインによるデータの漏洩や改竄、削除をされる危険性があり、セキュリティが脆弱だといえます。そこで、phpとMySQLを用いて具体的な対策方法を示します。

プレースホルダによる対策方法

接続先のデータベース名はform、テーブル名はuser_info、列はname、passwordにしてあります。通常、入力したユーザー名とパスワードがデータベースの中にあるかチェックする場合、以下のようなSQL文を書きます。

$sql = "SELECT name, password FROM user_info WHERE name='$username' AND password='$password'";
        $stmt = $dbh->prepare($sql);
        $stmt->execute();

しかし、これでは

$username : user1
$userpass : ' OR 'A' = 'A

のような入力がされた場合にSQLインジェクションが起きてしまいます。ここでは、WHEREの条件式が一旦、「’」によって終了された後に必ず真となる条件式を挿入しているため、不正ログインができてしまいます。

そこで、以下のようなプログラムに変更します。

$sql = "SELECT name, password FROM user_info WHERE name=? AND password=?";
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(1, $username, PDO::PARAM_STR);
        $stmt->bindParam(2, $password, PDO::PARAM_STR);
        $stmt->execute();

ここで変更した点はWHERE句の中の変更とbindParamの追加を行っています。WHERE句に挿入されている「?」がプレースホルダでパラメータを埋め込むことができるようにしています。また、bindParamはカッコ内の1つ目でパラメータを指定し、2つ目で変数を指定しています。ちなみに、3つ目は型を指定しています。これによって、データベースと入力値を結びつけることが出来、SQLインジェクションが起きなくなります。