SQLインジェクション対策に対応できていません
何故そう思うのですか? SQL 文をユーザーが入力した文字列を使って組み立てているからですか?
であれば、SQL 文をパラメータ化してはいかがですか?
何故パラメータ化が SQL インジェクション防止に役立つかは、ADO.NET + SQL Server の例ですが、以下の記事を見てください。
上の記事からもリンクが貼ってありますが、一般的な話として以下の記事も参考になると思います。
Are you sure you want to delete the question?
Leaving a resolved question undeleted may help others!
検索ワードの配列を使ってPHP+SQLのSELECT文をつくり、結果は正しく表示されますが SQLインジェクション対策に対応できていません、アドバイスがありましたらお願いいたします
$Keyword = 'ワード1 ワード2 ワード3';
$KeywordList = mb_split("[ ]", $Keyword);
$countKeyword = count($KeywordList);
for ($i = 0; $i < $countKeyword; $i++) {
if ($i == 0) {
$searchword = "((concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like '%".$KeywordList[$i]."%')";
} else {
$searchword .= " AND (concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like '%".$KeywordList[$i]."%')"
}
}
$searchword .= ")";
try {
$db = new PDO('mysql:dbname='.xxxxx.'; host='.xxxxx.'; charset=utf8', xxxxx, xxxxx);
} catch(PDOException $e) {
echo '接続エラー:' . $e->getMessage();
}
$db->query('SET NAMES utf8');
$stmt = $db->prepare("SELECT * FROM テーブル名 WHERE $searchword order by yoyaku_date desc");
// ↓ これを使ってチャレンジしたが失敗
// $stmt = $db->prepare("SELECT * FROM テーブル名 WHERE :searchword order by yoyaku_date desc");
// $stmt->bindParam(':searchword', $searchword, PDO::PARAM_STR);
$stmt->execute();
foreach ($stmt as $row) {
$row['yoyaku_name']." - ".$row['yoyaku_tel'].." - ".$row['yoyaku_comment']."<br>";
}
SELECT文内に変数を使うのはマズいと思い、下記を使って頑張りましたがエラーで出ずに結果が空白でした
$stmt = $db->prepare("SELECT * FROM テーブル名 WHERE :searchword order by yoyaku_date desc");
$stmt->bindParam(':searchword', $searchword, PDO::PARAM_STR);
SQLインジェクション対策に対応できていません
何故そう思うのですか? SQL 文をユーザーが入力した文字列を使って組み立てているからですか?
であれば、SQL 文をパラメータ化してはいかがですか?
何故パラメータ化が SQL インジェクション防止に役立つかは、ADO.NET + SQL Server の例ですが、以下の記事を見てください。
上の記事からもリンクが貼ってありますが、一般的な話として以下の記事も参考になると思います。
コメントありがとうございます
私の理解不足でした、リンク先を読んで勉強させて頂きます
$stmt = $db->prepare("SELECT * FROM テーブル名 WHERE :searchword order by yoyaku_date desc");
$stmt->bindParam(':searchword', $searchword, PDO::PARAM_STR);
これがうまく動かないのは変数$searchword
が部分的なSQLだからだと思います。
SQLインジェクションはパラメータに部分的なSQLを仕込んで想定外の動作をさせる攻撃なので、その対策をした結果として、searchwordパラメータの部分的なSQLが機能していない状態だと想像します。
解決方法は、パラメータの部分のみ動的にバインドします。
- $searchword .= " AND (concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like '%".$KeywordList[$i]."%')"
+ $searchword .= " AND (concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like '%:keyword".$i."%')"
$stmt->bindParam(':keyword'.$i, $KeywordList[$i], PDO::PARAM_STR);
コメントありがとうございます
アドバイス頂いた内容でとても勉強になりました
月曜に出社したら試して再度コメントを書きますね
【追記】
ありがとうございます、上手くいきました!
『 ':keyword'.$i 』という発想がなく、とても勉強になりました
$Keyword = 'ワード1 ワード2 ワード3'; // ワード数は可変
$KeywordList = mb_split("[ ]", $Keyword);
$countKeyword = count($KeywordList);
for ($i = 0; $i < $countKeyword; $i++) {
if ($i == 0) {
$searchword .= "((concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like :keyword".$i.")";
} else {
$searchword .= " AND (concat(yoyaku_name,yoyaku_tel,yoyaku_comment) like :keyword".$i.")";
}
}
$searchword .= ')';
try {
$db = new PDO('mysql:dbname='.xxxxx.'; host='.xxxxx.'; charset=utf8', xxxxx, xxxxx);
} catch(PDOException $e) {
echo '接続エラー:' . $e->getMessage();
}
$db->query('SET NAMES utf8');
$stmt = $db->prepare("SELECT * FROM テーブル名 WHERE $searchword order by yoyaku_date desc");
for ($i = 0; $i < $countKeyword; $i++) {
$KeywordList[$i] = '%'.$KeywordList[$i].'%';
$stmt->bindParam(':keyword'.$i, $KeywordList[$i], PDO::PARAM_STR);
}
$stmt->execute();
foreach ($stmt as $row) {
$row['yoyaku_name']." - ".$row['yoyaku_tel']." - ".$row['yoyaku_comment']."<br>";
}