SQLインジェクションとは、SQLの汚染、つまりはSQLのだめなところを直すためのもの
例えば、select * from user_master where id = (ユーザーからの入力値)
というsql文がプログラム内に組み込まれていたとする。
想定としてはユーザがuser_masterテーブルに入っているかを検索するためのsqlであり、ログインできるかどうかをチェックする
しかし、ユーザーがログインidを入力するのではなく、
例えば「1 or 1 = 1」と入力した場合、上のsql文は、
select * from user_master where id = 1 or 1 = 1
となり、whereの条件文がTrueになるレコードは全てなので、全ての情報を抜き出されてしまう可能性があります。(1 = 1はどんなレコードでもtrueになるため)
こうならないように、エスケープして上記の入力値の箇所に当てはめるようにするのが、
プリペアドステートメントといいます。
$dbname = "mysql:dbname=test;host=34.84.23.6"; $user = "root"; $pass = "modulo78"; $dbh = new PDO($dbname, $user, $pass); $id = 1; $sql = 'Select name From test.test_table where id=:id'; $stmt = $dbh->prepare($sql); $stmt->execute([":id" =>; $id]); #$result = $stmt->fetchAll(PDO::FETCH_ASSOC); $result = $stmt->fetchAll(); print($result); [/php]
コードを見ると、
$stmt->execute([":id" => $id])
とすることで一回エスケープしてsqlに入れてくれる。
sql内の:idに変数idの値を入れるようにする。直接入れるのではなく、:idに置き換えて間接的に付与することで、
エスケープ処理を行なっている。
SQLインジェクションについてお話しします。
SQLインジェクションとは、SQLの汚染?と直訳したらなりますが、要はデータを抜き出すというもので、
select * from table where id = (ユーザーが入力した値)
というのをよくバックエンドで設定していることがある。
このユーザーが入力した値が100とか想定通りの値を入れてきた場合はいいと思うが、もし 1 or 1 = 1と入力してそれを上記のsql文に入れると、
select * from table where id = 1 or 1 = 1
となり、1 = 1は必ずTrueで1 = 1を満たすデータは全てである。そのため、全件取得されてしまう。
このようにユーザーが入力したものに対してなんらかの処理をかます必要がある。これをプリペアドステートメントという。
やり方は簡単で、
select * from table where id = :id
$param = [":id" => $id]としてphpはインタプリタ言語(スクリプト言語)なので1行ずつの解析であるので、一回上記のように書いてコンパイルをしておくことで弾くことができるようになる。