0Pricing
PHP Academy · レッスン

SQLインジェクションとパラメータ化クエリ

常にPDOのプリペアドステートメントを使ってインジェクションのリスクをなくします

「SQLインジェクションとパラメータ化クエリ」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。

SQLインジェクションとは

SQLインジェクションとは、ユーザーから提供されたデータをSQLクエリに直接埋め込むことで、攻撃者がクエリを操作し、データへのアクセス、変更、削除を可能にする攻撃です。

典型的な例

ユーザー入力をSQLに連結します:

<?php
// VULNERABLE: attacker enters username = "' OR '1'='1"
$sql = "SELECT * FROM users WHERE username = '".$_GET["username"]."'";
// Becomes: SELECT * FROM users WHERE username = '' OR '1'='1'
// Returns ALL users!

データ流出の例

攻撃者はUNION SELECTを使って、他のテーブルからデータを流出させます。

// Input: ' UNION SELECT username, password FROM admin_users--
// This appends a second SELECT returning admin credentials

プリペアドステートメントが解決策

プリペアドステートメントでは、データが提供される前にクエリ構造が固定されます。データベースは、バインドされた値をすべてリテラルデータとして扱い、SQLコードとして扱うことはありません。

<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_GET["username"]]);
// Safe even if username = "' OR 1=1--"

名前付きプレースホルダー

名前付きプレースホルダーは、特にパラメーターが複数ある場合に、より明確になります。

<?php
$stmt = $pdo->prepare(
    "SELECT * FROM users WHERE email = :email AND active = :active"
);
$stmt->execute([":email" => $email, ":active" => true]);

Eloquentはデフォルトで安全

Laravel Eloquentは、標準的なすべてのクエリビルダー操作で、内部的にPDOのプリペアドステートメントを使用します。

<?php
// Safe:
User::where("email", $email)->first();

// UNSAFE: raw query with user input!
DB::select("SELECT * FROM users WHERE email = ".$email);

生SQLクエリ

Laravelで生SQLを使用する必要がある場合は、必ずパラメーターバインディングを使用してください。

<?php
// Safe raw query:
$users = DB::select("SELECT * FROM users WHERE email = ?", [$email]);

// Or with named bindings:
$users = DB::select("SELECT * FROM users WHERE email = :email", [":email" => $email]);

LIKE句のインジェクション

LIKE句には特別な処理が必要です。ワイルドカード文字(%、_)は、バインドする前に手動でエスケープする必要があります。

<?php
$search = str_replace(["%", "_", "\\"], ["\%", "\_", "\\\\"], $userInput);
$stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ?");
$stmt->execute(["%$search%"]);

ORDER BYインジェクション

カラム名とORDER BYの方向はパラメーター化できません。ホワイトリストと照合して検証してください。

<?php
$allowedColumns = ["name", "price", "created_at"];
$col = in_array($request->sort, $allowedColumns) ? $request->sort : "name";
$dir = $request->dir === "desc" ? "desc" : "asc";
// Then safely build the query string

ストアドプロシージャ

ストアドプロシージャも、内部で入力を連結している場合は脆弱になる可能性があります。必ずパラメーター化された呼び出しを使用してください。

最小権限の原則

PHPから接続するデータベースユーザーには、必要なテーブルに対するSELECT/INSERT/UPDATE/DELETEだけを許可し、CREATE、DROP、管理者権限は決して付与しないでください。

概要

バインドパラメーター付きのプリペアドステートメントを必ず使用してください。ユーザー入力をSQLに連結しないでください。ORDER BYとカラム名はホワイトリストと照合して検証してください。エミュレートプリペアを無効にしたPDOを使用してください。

確認問題

SQLインジェクションを防ぐ正しい方法は何ですか?

よくある質問

「SQLインジェクションとパラメータ化クエリ」レッスンは無料ですか?

はい。「SQLインジェクションとパラメータ化クエリ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。

「SQLインジェクションとパラメータ化クエリ」で何を学びますか?

常にPDOのプリペアドステートメントを使ってインジェクションのリスクをなくします ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

PHP Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「SQLインジェクションとパラメータ化クエリ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPHP Academyレッスンでコードを書いて実行できますか?

はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. クロスサイトスクリプティング(XSS)の防止
  2. SQLインジェクションとパラメータ化クエリ
  3. CSRF対策
  4. パスワードの安全な保存
← PHP Academyに戻る