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インジェクションが起きなくなります。