ホームページ >バックエンド開発 >PHPチュートリアル >PHP_PHP チュートリアルで SQL インジェクションを防ぐ最善の方法について説明します。

PHP_PHP チュートリアルで SQL インジェクションを防ぐ最善の方法について説明します。

WBOY
WBOYオリジナル
2016-07-21 15:06:50951ブラウズ

ユーザーが SQL ステートメントに直接挿入されるクエリを入力すると、アプリケーションは次の例のように SQL インジェクションに対して脆弱になります:

コードをコピーします コードは次のとおりです:

$ unsafe_variable = $_POST[ 'user_input'];
mysql_query("INSERT INTO table (column) VALUES ('" . $unsafe_variable . "')");

これは、ユーザーが VALUE のようなものを入力できるためです"); DROP TABLE table; - , make クエリは次のようになります:
コードをコピーします。 コードは次のとおりです:
INSERT INTO table (column) VALUES('VALUE');'



この状況を防ぐにはどうすればよいでしょうか?以下を参照してください任意のパラメーターを含む SQL ステートメントはデータベース サーバーに送信され、解析されます。
この目標には基本的に 2 つのオプションがあります:
1. PDO (PHP データ オブジェクト) を使用します:

コードをコピーします コードは次のとおりです:
$stmt = $pdo->prepare( 'SELECT * FROM 従業員 WHERE name = :name');
$stmt->execute(array(':name' => $name));
foreach ($stmt as $row) {
// 何かをするwith $ row
}



2. mysqli を使用します:
コードをコピーします コードは次のとおりです:
$stmt = $dbConnection->prepare('SELECT * FROM 従業員 WHERE name = ?') ;
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result-> ;fetch_assoc()) {
// $row
}で何かをする



PDO (PHP Data Object)
PDO を使用して MySQL データベースにアクセスする場合、実際のプリペアド ステートメントはこの問題を解決するには、プリペアド ステートメントのエミュレーションを無効にする必要があります。
PDO を使用して接続を作成する例は次のとおりです:

コードをコピーします コードは次のとおりです:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0. 0.1;charset=utf8', ' user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ;


上記の例では、エラー モード ERRMODE は厳密には必須ではありませんが、追加することをお勧めします。このメソッドは、致命的なエラーが発生した場合でもスクリプトを停止しません。そして、開発者にエラー (PDOException がスローされたとき) を捕捉する機会を与えます。
setAttribute() 行は必須であり、エミュレートされたプリペアド ステートメントを無効にし、実際のプリペアド ステートメントを使用するように PDO に指示します。これにより、ステートメントと値が MySQL データベース サーバーに送信される前に PHP によって解析されなくなります (攻撃者が悪意のある SQL を挿入する可能性はありません)
もちろん、コンストラクター オプションで文字セット パラメーターを設定することもできます。 「古い」PHP バージョン (5.3.6) は、DSN の文字セット パラメータを無視することに特に注意してください。

説明
渡したSQLプリペアドステートメントがデータベースサーバーによって解析され、コンパイルされるとどうなりますか?文字 (上の例では a? や like: name など) を指定して、データベース エンジンにフィルタリングする内容を伝えます。次に、execute を呼び出して、指定したパラメーター値と組み合わせて準備されたステートメントを実行します。 、パラメーター値は、SQL 文字列ではなく、プリコンパイルされたステートメントと結合されます。SQL インジェクションは、悪意のある文字列を含む SQL スクリプトを不正に作成し、それをデータベースに送信することによって機能します。そのため、実際の別の SQL パラメーターを送信します。プリペアド ステートメントを使用する場合、送信するパラメータは文字列としてのみ扱われます (ただし、データベース エンジンはパラメータの最適化を行う可能性がありますが、上記の例では、最終的には数値になる可能性があります)。変数 $name に 'sarah';DELETE * FROMemployees が含まれている場合、結果は検索文字列 "'sarah';DELETE * FROMemployees" のみとなり、空のテーブルは取得されません。
プリペアド ステートメントを使用するもう 1 つの利点は、同じセッション内で同じステートメントを複数回実行する場合、解析とコンパイルが 1 回だけで済み、速度がある程度向上することです。
ああ、挿入方法を尋ねられたので、ここに例を示します (PDO を使用):



コードをコピーします

コードは次のとおりです:

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
$preparedStatement->execute(array(':column' => $unsafeValue));

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/327586.html技術記事ユーザーが SQL ステートメントに直接挿入されるクエリを入力すると、アプリケーションは次の例のように SQL インジェクションに対して脆弱になります。 次のようにコードをコピーします: $unsafe_variable =...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。