ホームページ > バックエンド開発 > PHPチュートリアル > php_PHPチュートリアルでのSQLインジェクションの詳細説明と防止

php_PHPチュートリアルでのSQLインジェクションの詳細説明と防止

WBOY
リリース: 2016-07-13 10:25:23
オリジナル
891 人が閲覧しました

1 つは入力データがフィルターされていない (フィルター入力) こと、もう 1 つはデータベースに送信されるデータがエスケープされていない (エスケープ出力) ことです。これら 2 つの重要な手順は不可欠であり、プログラム エラーを減らすために特別な注意が必要です。
攻撃者にとって、SQL インジェクション攻撃を実行するには、思考と実験が必要です。データベース ソリューションについて十分に根拠のある推論を行うことが非常に必要です (もちろん、攻撃者がソース プログラムとデータベース ソリューションを参照できないことを前提としています)。次の単純なログイン フォームを考えてみましょう。 :

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


ユーザー名:


パスワード:





攻撃者として、彼はクエリ ステートメントを推測してユーザー名とパスワードを確認することから始めます。ソースファイルを見ることで、彼はあなたの習慣を推測し始めることができます。
たとえば、名前の習慣。通常、フォーム内のフィールド名はデータ テーブル内のフィールド名と同じであると想定されます。もちろん、それらが異なることを保証することが、必ずしも信頼できるセキュリティ対策であるとは限りません。
最初の推測として、通常は次の例のクエリを使用します:
コードをコピーします コードは次のとおりです:

$password_hash = md5($_POST['password ']);

$sql = "SELECT count(*)
FROM users
WHERE username = '{$_POST['username']}'
AND パスワード = '$password_hash'";

ユーザー パスワードの MD5 値を使用する これは以前は一般的な方法でしたが、現在は特に安全ではありません。最近の研究では、MD5 アルゴリズムには欠陥があり、多数の MD5 データベースによって MD5 逆クラッキングの難易度が低下していることが示されています。デモを見るには http://md5.rednoize.com/ にアクセスしてください (原文どおり。山東大学の Wang Xiaoyun 教授の研究によると、MD5 の「衝突」、つまり、衝突を引き起こす 2 つの異なるファイルと単語がすぐに見つかることがわかっています。ただし、この結果によると、上記の特殊な場合に md5 を直接使用するのは危険です。)
最善の保護方法は、独自に定義した文字列をパスワードに追加することです。例:


コードをコピーします コードは次のとおりです:
$salt = 'SHIFLETT' ;
$password_hash = md5($salt . md5($_POST['password'] . $salt));
?>


もちろん、攻撃者は最初からそれを正しく推測できない可能性があり、多くの場合、それを正しく推測する必要があります。いくつかの実験をしてください。実験するより良い方法は、ユーザー名として一重引用符を入力することです。これにより、重要な情報が公開される可能性があります。多くの開発者は、Mysql ステートメントの実行中にエラーが発生したときに、関数 mysql_error() を呼び出してエラーを報告します。以下の例を参照してください:


コードをコピーします コードは次のとおりです:
mysql_query($sql) or exit(mysql_error());
?>


ただし、これはこのメソッドは開発中です。非常に便利ですが、重要な情報が攻撃者に公開される可能性があります。攻撃者がユーザー名として一重引用符を使用し、パスワードとして mypass を使用した場合、クエリ ステートメントは次のようになります:

コードをコピーします コードは次のとおりです:
$sql = "SELECT *
FROM ユーザー
where username = '' '
andpassword =' A029d0df84EB5549C641E04A9EF389E5 '";
? & GT; 以下のように :


SQL 構文にエラーがあります。使用している言語に対応するマニュアルを確認してください。 'WHERE username = ''' AND
password = 'a029d0df84eb55

付近で使用する適切な構文の MySQL サーバー バージョン 簡単に、攻撃者は 2 つのフィールド名 (ユーザー名とパスワード) とそれらのフィールドの出現順序をすでに知っています。クエリ。さらに、攻撃者は、データが正しくフィルタリングされず (プログラムが不正なユーザー名を要求しません)、エスケープされ (データベース エラーが発生します)、WHERE 条件全体の形式も公開されていることも知っています。操作してみます クエリに一致するレコードがあります。 この時点で、攻撃者には多くの選択肢があります。 1 つは、ユーザー名とパスワードが一致するかどうかに関係なくクエリを照合できるように、特別なユーザー名を入力してみる方法です:
コードをコピーします

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

myuser' または 'foo' = 'ふー' --

A mypass がパスワードとして使用されていると仮定すると、クエリ全体は次のようになります:

コードをコピー 次のようにコード:
& lt;? Php

$ sql = "select *

users
where username = 'myuser' OR 'FOO' = 'FOO' --
And Password = 'A029d0df84EB5549C641E04A9EF389E5' ";

? & gt; 幸いなことに、SQL インジェクションは簡単に回避できます。前に述べたように、入力をフィルタリングし、出力をエスケープする必要があります。
どちらのステップも省略することはできませんが、いずれかのステップを実装すると、ほとんどの SQL インジェクションのリスクを排除できます。出力をエスケープせずに入力をフィルタリングするだけの場合、データベース エラーが発生する可能性があります (正当なデータも SQL クエリの正しい形式に影響を与える可能性があります)。ただし、これも信頼性が低く、正当なデータによって SQL の動作が変わる可能性もあります。声明。一方、入力をフィルタリングせずに出力をエスケープすると、データが SQL ステートメントの形式に影響を与えないようにすることができ、多くの一般的な SQL インジェクション攻撃手法も防ぐことができます。
もちろん、これら 2 つのステップを同時に使用することを主張する必要があります。入力をフィルタリングする方法は、入力データのタイプに完全に依存します (第 1 章の例を参照) が、データベースに送信するために出力データをエスケープする場合は、同じ関数を使用するだけです。 MySQL ユーザーの場合、関数 mysql_real_escape_string() を使用できます:



コードをコピーします
コードは次のとおりです: $clean = array();
$mysql = array() ;

$clean[ 'last_name'] = "オライリー";
$mysql['last_name'] = mysql_real_escape_string($clean['last_name']);

$sql = "INSERT
INTO user (last_name)
VALUES ('{$ mysql['last_name']}')";
?>


データベース用に設計されたエスケープ関数を使用してみてください。そうでない場合は、addslashes() 関数を使用することが最終的でより良い方法です。
SQL ステートメントの構築に使用されるすべてのデータが適切にフィルタリングされ、エスケープされると、SQL インジェクションのリスクが実際に回避されます。パラメータ化されたクエリとプレースホルダ (PEAR::DB、PDO など) をサポートするデータベース操作クラスを使用している場合、追加の保護層が得られます。以下の PEAR::DB の使用例を参照してください:


コードをコピーします
コードは次のとおりです: $sql = 'INSERT
INTO user (last_name)
VALUES (?) ';
$ dbh->query($sql, array($clean['last_name']));
?>


上記の例のデータはクエリ ステートメントの形式に直接影響を与えることができないため、 SQL インジェクションのリスクが軽減されます。 PEAR::DB はデータベースの要件に従って自動的にエスケープするため、出力をフィルタリングするだけで済みます。
パラメータ化されたクエリステートメントを使用している場合、入力コンテンツはデータとしてのみ処理されます。これにより、エスケープする必要がなくなりますが、出力をエスケープする習慣を守りたい場合は、エスケープすることが必要な手順であると考えることもできます。実際、この時点で変換する必要がある特殊文字がないため、この時点でエスケープするかどうかは基本的に影響しません。パラメーター化されたクエリは、SQL インジェクションの防止に関してプログラムに強力な保護を提供します。
注: SQL インジェクションに関しては、現在、ほとんどの仮想ホストで magic_quotes_gpc オプションがオンになっていると言わなければなりません。この場合、すべてのクライアントの GET および POST データは addslashes によって自動的に処理されるため、現時点では文字列値の SQL インジェクションは行われません。可能ですが、intval()などの関数による処理など、数値のSQLインジェクションを防ぐ必要があります。ただし、汎用ソフトウェアを作成している場合は、サーバーの magic_quotes_gpc を読み取り、それに応じて処理する必要があります。


http://www.bkjia.com/PHPjc/825126.html

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/825126.html技術記事 1 つは入力データがフィルターされていない (フィルター入力) こと、もう 1 つはデータベースに送信されるデータがエスケープされていない (エスケープ出力) ことです。この 2 つの重要なステップは不可欠です...
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート