説明
ユーザー入力をSQL文字列に直接連結し、mysqli_query、query、exec などのAPIで実行すると、SQLインジェクションが発生するおそれがあります。
想定される影響
認証の回避、データの漏えい、改ざん、削除につながる可能性があります。
対処方法
PDOまたはmysqliのプリペアドステートメントを使い、値はパラメーターとしてバインドします。動的なテーブル名や列名は許可リストで制限します。
例
変更前
php
<?php
$id = $_REQUEST['id'];
$query = "SELECT * FROM users WHERE user_id = '$id'";
mysqli_query($db, $query);
変更後
php
<?php
$id = intval($_REQUEST['id']);
$stmt = $pdo->prepare('SELECT * FROM users WHERE user_id = :id');
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
解説:
- 変更前: リクエストの入力値をSQL文に直接埋め込んでいます。
- 変更後: プリペアドステートメントで、バインドした値をデータとして扱います。