topic: db (PDO / SQL / マルチDB) / ch09

ch09 — SQL インジェクション / プリペアド vs 連結

学習目標

  • 文字列連結で SQL を組み立てる危険性を体感する
  • プレースホルダ (?) + prepare/execute がなぜ安全なのか、その理由を言える
  • ユーザー入力に特殊文字 (';) が混ざっても壊れない書き方が分かる

所要時間

スライド 5 分 + ドリル 2 問 = 18 分

ドリル

no 内容
01 文字列連結で書かれた starter を、プレースホルダ版に直す (' 入りの名前で動作確認)
02 検索フォーム想定。LIKE 検索でもプレースホルダを使う

採点用 DB について

採点ランナーは tests/setup.sql を一時 SQLite に流し込み、そのファイルパスを環境変数 DOJO_DB_PATH で渡してきます。受講生コードは次の形で接続してください。

$pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
▶ 3v4l で実行

なぜ文字列連結が危険か

// ❌ 危険: 入力をそのまま SQL に連結
$name = $_GET['name'];
$sql = "SELECT * FROM users WHERE name = '$name'";
▶ 3v4l で実行

ユーザーが name=' OR '1'='1 を入れると、SQL は

SELECT * FROM users WHERE name = '' OR '1'='1'

になり、全件返ってくる。さらに悪意ある入力で '; DROP TABLE users; -- を渡されると、テーブル自体を壊される可能性がある。

プレースホルダ版なら、入力は として扱われるので SQL 構文として解釈されない。

演習問題(2問)

  1. ドリル 01 — 連結をプレースホルダに直す

    starter.php answer.php

  2. ドリル 02 — LIKE 検索もプレースホルダで

    starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリ(nomuraya-dojo/php)を clone してください。