ホームページ > バックエンド開発 > PHPチュートリアル > php SQL インジェクションと anti-injection_PHP チュートリアルの古典的なケース分析

php SQL インジェクションと anti-injection_PHP チュートリアルの古典的なケース分析

WBOY
リリース: 2016-07-13 17:10:26
オリジナル
1422 人が閲覧しました

SQL インジェクションとインジェクション防止は、実際には攻撃と防御の組み合わせです。今日は、最も基本的なインジェクションと防止方法を説明します。これらの原理はすべて、私たちが注意を払わずに PHP または MySQL の機能を使用することによって引き起こされます。

単純な SQL インジェクション攻撃ケース
会社の Web サイトがある場合、すべての顧客データとその他の重要な情報は Web サイトのバックエンド データベースに保存されます。 Web サイトのログイン ページのコードにユーザー情報を読み取るコマンドが含まれている場合。

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

$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. ;

?>

今、あなたのデータベースを攻撃しようとしているハッカーが、このログイン ページのユーザー名入力ボックスに次のコードを入力しようとしています。

コードは次のとおりですコードをコピーログインボタンをクリックすると、このページにデータベース内のすべてのテーブルが表示されます。彼が次のコマンド行を使用するとします:
' ; テーブルを表示します。

コードは次のとおりです'; DROP TABLE [テーブル名];このようにして、テーブルを削除しました!
コードをコピー

もちろん、これは非常に単純な例にすぎません。実際の SQL インジェクション方法はこれよりもはるかに複雑で、ハッカーは喜んでコードを攻撃しようと多くの時間を費やします。 SQL インジェクション攻撃を自動的に継続的に試行できるソフトウェア プログラムがいくつかあります。 SQL インジェクションの攻撃原理を理解した後、SQL インジェクション攻撃を防ぐ方法を見てみましょう。

magic_quotes_gpc = Onの場合のインジェクション攻撃

magic_quotes_gpc = On の場合、攻撃者は文字フィールドに対して SQL インジェクションを実行できません。だからといって安全というわけではありません。現時点では、SQL インジェクションは数値フィールドを通じて実行できます。


最新バージョンのMYSQL 5.xでは、データ型の入力が厳格化され、自動型変換がデフォルトでオフになっています。数値フィールドを引用符でマークされた文字タイプにすることはできません。言い換えれば、uid が数値であると仮定すると、以前の mysql バージョンでは、このようなステートメントは正当です:

コードは次のとおりですINSERT INTO tbl_user SET uid="1"; 最新の MYSQL 5.x では、上記のステートメントは合法ではないため、次のように記述する必要があります:
コードをコピー
SELECT * FROM tbl_user WHERE uid="1";


コードは次のとおりですtbl_user SET uid=1 に挿入;

これは正しいと思います。開発者として、ルールに準拠した正しいデータ型をデータベースに送信することが最も基本的な要件だからです。

では、magic_quotes_gpc = Onの場合、攻撃者はどのように攻撃するのでしょうか?非常に簡単で、数値フィールドに対して SQL インジェクションを実行するだけです。次の php スクリプトを例として取り上げます:

コードをコピー
SELECT * FROM tbl_user WHERE uid=1;


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


if ( isset($_POST["f_login"] ) )
{
// データベースに接続します...
//...コードは省略されています...

// ユーザーが存在するかどうかを確認します
$t_strUid = $_POST["f_uid"];
$t_strPwd = $_POST["f_pwd"];
$t_strSQL = "SELECT * FROM tbl_users WHERE uid=$t_strUid AND パスワード = '$t_strPwd' LIMIT 0,1";
if ( $t_hRes = mysql_query($t_strSQL) )
{
// クエリが成功した後の処理 少し...
}

}
?>
サンプルテスト



<フォームメソッド=ポストアクション="">
ユーザー ID:

パスワード:




上記のスクリプトでは、ユーザーはログインするためにユーザー ID とパスワードを入力する必要があります。通常のステートメントでは、ユーザーは 1001 と abc123 を入力し、送信された SQL ステートメントは次のとおりです:

コードは次のとおりです コードをコピー
SELECT * FROM tbl_users WHERE userid=1001 AND パスワード = 'abc123' LIMIT 0,1

攻撃者が「1001 OR 1 =1 # at userid」と入力した場合、挿入される SQL ステートメントは次のようになります。

コードは次のとおりですコードをコピーSELECT * FROM tbl_users WHERE userid=1001 OR 1 =1 # AND パスワード = 'abc123' LIMIT 0,1

攻撃者は目的を達成した。

SQL インジェクションを防止 - mysql_real_escape_string() 関数を使用します

データベースオペレーションコードでこの関数 mysql_real_escape_string() を使用して、引用符などのコード内の特殊文字を除外します。例として:

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

SQL インジェクションを防止 - mysql_query() 関数を使用します

mysql_query() の特別な点は、SQL コードの最初の行のみが実行され、後続の行は実行されないことです。前の例で、ハッカーがコードを通じてバックグラウンドで複数の SQL コマンドを実行し、すべてのテーブルの名前を表示したことを思い出してください。したがって、mysql_query() 関数はさらなる保護を実現できます。今のコードをさらに進化させて、次のコードを取得します:

$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ) " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password' ] )。

?>

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

//接続
$database = mysql_connect("localhost", "ユーザー名","パスワード");

//データベースの選択
mysql_select_db("データベース", $database);

$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['パスワード'] )、$database);

?>

さらに、PHP コード内の入力値の長さを判断したり、関数を使用して入力値を確認したりすることもできます。したがって、ユーザー入力値が受け入れられる場合は、入力内容をフィルタリングしてチェックする必要があります。もちろん、意図的な防止を実現するために、最新の SQL インジェクション手法を学び理解することも非常に重要です。 WordPress などのプラットフォーム Web サイト システムを使用している場合は、必ず公式パッチを適用するか、適時に新しいバージョンにアップグレードしてください。何か間違っている場合や理解できない場合は、コメント欄にメッセージを残してください。

php.iniのdisplay_errorsオプションはdisplay_errors = offに設定する必要があります。これにより、php スクリプトでエラーが発生した後は、Web ページにエラーが出力されなくなり、攻撃者による有用な情報の分析が防止されます。

mysql_query などの mysql 関数を呼び出すときは、mysql エラーが出力されないように、先頭に @ を追加する必要があります (@mysql_query(...))。攻撃者が有益な情報を分析できないようにする場合も同様です。さらに、一部のプログラマーは、開発時に mysql_query エラーが発生したときにエラーと SQL ステートメントを出力することに慣れています。例:

コードは次のとおりですコードをコピー$t_strSQL = "b....から a を選択";
if ( mysql_query($t_strSQL) )
{
// 正しい取り扱い
}
それ以外
{
echo "エラー! SQL ステートメント: $t_strSQL rn エラー メッセージ".mysql_query();
終了します;
}
このやり方はかなり危険で愚かです。これを行う必要がある場合は、グローバル変数を設定するか、Web サイト設定ファイルでマクロを定義してデバッグ フラグを設定することをお勧めします。

グローバル設定ファイル内:

コードは次のとおりですコードをコピーdefine("DEBUG_MODE",0); // 1: デバッグモード 0: リリースモード; //呼び出しスクリプト内:

コードは次のとおりです$t_strSQL = "b....から a を選択"; if ( mysql_query($t_strSQL) )
コードをコピー
{
// 正しい取り扱い
}
それ以外は
{
if (デバッグ_モード)
echo "エラー! SQL ステートメント: $t_strSQL rnエラー メッセージ".mysql_query();
終了します;
}

SQL アンチインジェクションコンテンツについて http://www.bKjia.c0m/phper/phpanqn/37704.htm


www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/629669.html技術記事 SQL インジェクションとインジェクション防止は、実際には攻撃と防御の組み合わせです。今日は、最も基本的なインジェクションと防止方法について説明します。これらの原則はすべて、これまで注目していなかった PHP または MySQL のいくつかの機能に基づいています。 .
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート