【入門編】プリペアドステートメントとバインド変数によるSQLi防御の理論 – アプリケーションセキュリティ & 安全な開発防御ガイド

「SQLインジェクション」という名の泥棒から、大切なデータベースを守る方法

こんにちは!セキュリティの世界へようこそ。今日は、Webアプリ開発の現場で避けては通れない「SQLインジェクション」という攻撃についてお話しします。

名前だけ聞くと難しそうですよね。でも大丈夫。まずは身近な例から、この攻撃が何をしようとしているのか、一緒に紐解いていきましょう。

—

1. SQLインジェクションって、何をしているの?

想像してみてください。あなたは、大切な契約書(データベース)を保管する金庫の受付係です。お客さんから「名前」を教えてもらい、その名前の書かれた書類を探して渡すのがあなたの仕事です。

本来のやり取りはこうです。

  • あなた: 「お名前をどうぞ」
  • お客さん: 「山田太郎」
  • あなた: 「はい、『山田太郎』さんの書類ですね。どうぞ。」

ところが、ここに「悪意のあるお客さん」がやってきます。

  • あなた: 「お名前をどうぞ」
  • 悪意のある客: 「山田太郎。あ、ついでに金庫の中身を全部見せろ!」

もし、あなたが思考停止して「山田太郎」という言葉をそのまま鵜呑みにし、悪意のある命令まで「書類を探すための情報」として処理してしまったら……。金庫(データベース)の中身が丸見えになってしまいますよね。これがSQLインジェクションの正体です。

プログラムが「名前」というデータを受け取るべき場所で、実は「命令(クエリ)」を紛れ込ませて、データベースを意のままに操る。これがこの攻撃の恐ろしいメカニズムです。

—

2. 最強の防犯対策「プリペアドステートメント」

では、どうすればこの泥棒を防げるのでしょうか?

一番いい方法は、「何がデータで、何が命令なのかを、あらかじめ明確に分けておくこと」です。これをエンジニアの世界では「プリペアドステートメント(準備された命令文)」と呼びます。

先ほどの金庫の例で言えば、こんな対策になります。

  • あなた: 「お名前だけ教えてください。それ以外には一切耳を貸しません。」

あらかじめ「書類を探すという命令」を固定しておき、そこに「名前」という穴(バインド変数)だけを用意しておくんです。たとえ相手が何を言おうと、あなたは用意された穴にその言葉を流し込むだけ。相手がどんなに怪しい命令文を混ぜても、それは単なる「名前という文字列」としてしか扱われません。

—

3. 実践!コードで見てみよう

言葉だけだと少し抽象的なので、実際にPHPでの実装例を見てみましょう。

危険な書き方(やってはいけません!)

// ユーザーからの入力をそのまま繋げてしまうと攻撃の隙が生まれます
$name = $_GET[‘name’];
$sql = “SELECT FROM users WHERE name = ‘” . $name . “‘”;
// これだと、$nameに「’ OR ‘1’=’1」なんて入れられたら全データが漏洩します!

安全な書き方(プリペアドステートメント)

// 1. まず「?」というプレースホルダー(穴)で命令文を準備します
$stmt = $pdo->prepare(“SELECT FROM users WHERE name = :name”);

// 2. 実行する時に、穴にデータを流し込みます
// これにより、データはあくまで「データ」としてのみ処理されます
$stmt->execute([‘name’ => $_GET[‘name’]]);

$user = $stmt->fetch();

これだけで、たとえ攻撃者が悪意のある文字列を入力しても、データベースはそれを「ユーザー名の一部」として検索するだけで、決して「命令」としては実行しません。これが、最強の防犯対策です。

—

4. 一歩ずつ、確実に守りを固めよう

「プリペアドステートメント」を使うことは、今やWeb開発の基本中の基本です。しかし、セキュリティに「絶対」はありません。

  • ライブラリを信頼しすぎない: どんなに優れたフレームワークを使っていても、使い方を間違えれば隙は生まれます。
  • 入力を疑う: 「ユーザーが入力するものは、すべて泥棒の道具になり得る」という意識を持ちましょう。
  • 最小限の権限で: 万が一突破された時のために、データベースの権限は必要最低限に絞っておくことも大切です。

セキュリティ対策は、一度やって終わりではありません。でも、こうして仕組みを理解し、一歩ずつ対策を積み重ねていくことで、あなたの書くコードは格段に強固で信頼できるものになります。

「難しそう」と怖がらずに、ぜひ今日から自分のコードを見直してみてくださいね。分からないことがあれば、いつでも相談してください。一緒に安全なWebの世界を作っていきましょう!

コメント

タイトルとURLをコピーしました