ホームページ >バックエンド開発 >PHPチュートリアル >PDO プリペアド ステートメントは SQL インジェクション攻撃から本当に安全ですか?

PDO プリペアド ステートメントは SQL インジェクション攻撃から本当に安全ですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-26 01:48:09551ブラウズ

Are PDO Prepared Statements Truly Safe from SQL Injection Attacks?

PDO プリペアド ステートメントは SQL インジェクションの影響を受けませんか?

PDO ドキュメントでは、プリペアド ステートメントを使用すると手動でパラメーターを引用する必要がなくなると示唆していますが、答えは微妙なニュアンスで「はい」です。 。」 PDO はデフォルトで MySQL のプリペアド ステートメントをエミュレートしますが、このエミュレーションにより悪用可能な脆弱性が生じる場合があります。

攻撃ベクトル

潜在的な脆弱性は、接続エンコーディングに特定の脆弱な文字セット (gbk など) が含まれる場合に発生します。 、cp932) であり、次の条件が満たされています:

  1. データベースの文字セットは次のとおりです。 (mysql_set_charset() の代わりに) SET NAMES を使用して設定します。
  2. クライアントは、エミュレートされたプリペアド ステートメント (または、MySQL サーバーがエミュレートされたものとして扱う真のプリペアド ステートメント) を使用します。

そのような場合攻撃者は、無効なマルチバイト文字を含むペイロードを作成し、クライアントで予期される文字セットと実際の文字セットの不一致を悪用する可能性があります。接続の。これにより、生成されたクエリ文字列に引用符で囲まれていない文字が挿入される可能性があり、SQL インジェクションが発生する可能性があります。

修正

予防策:

  • エミュレートされたプリペアドステートメントを無効にします。 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
  • PDO DSN charset パラメーターを使用して文字エンコーディングを設定します (PHP >= 5.3.6): $pdo = new PDO('mysql :host=localhost;dbname=testdb;charset=gbk', $user, $password);
  • 脆弱なエンコーディングを避ける: この攻撃に対して脆弱ではない UTF-8 や Latin1 などの文字セットを使用します。

軽減策:

  • NO_BACKSLASH_ESCAPES SQL モードを有効にする: これにより、文字エスケープの動作が変更されます。

安全な例

次のコード スニペットは、安全な方法を示しています。

// PDO without emulated prepares
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("xbf' OR 1=1 /*"));

// PDO with DSN charset parameter
$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=gbk', $user, $password);
$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("xbf' OR 1=1 /*"));

// MySQLi (always uses true prepared statements)
$mysqli->query('SET NAMES gbk');
$stmt = $mysqli->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$param = "xbf' OR 1=1 /*";
$stmt->bind_param('s', $param);
$stmt->execute();

結論

PDO プリペアド ステートメントは、 SQL インジェクションを適切に使用し、安全な方法と組み合わせて効果的に防止します。潜在的な脆弱性を軽減するには、脆弱なエンコードを回避し、エミュレートされた準備を無効にするか、NO_BACKSLASH_ESCAPES モードを有効にすることが重要です。

以上がPDO プリペアド ステートメントは SQL インジェクション攻撃から本当に安全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。