SQL インジェクションとインジェクション防止は、実際には攻撃と防御の組み合わせです。今日は、最も基本的なインジェクションと防止方法を説明します。これらの原理はすべて、私たちが注意を払わずに PHP または MySQL の機能を使用することによって引き起こされます。
単純な SQL インジェクション攻撃ケース
会社の Web サイトがある場合、すべての顧客データとその他の重要な情報は Web サイトのバックエンド データベースに保存されます。 Web サイトのログイン ページのコードにユーザー情報を読み取るコマンドが含まれている場合。
コードは次のとおりです | コードをコピー |
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. ; ?> |
今、あなたのデータベースを攻撃しようとしているハッカーが、このログイン ページのユーザー名入力ボックスに次のコードを入力しようとしています。
コードをコピー | |
' ; テーブルを表示します。
|
コードをコピー | |
|
もちろん、これは非常に単純な例にすぎません。実際の SQL インジェクション方法はこれよりもはるかに複雑で、ハッカーは喜んでコードを攻撃しようと多くの時間を費やします。 SQL インジェクション攻撃を自動的に継続的に試行できるソフトウェア プログラムがいくつかあります。 SQL インジェクションの攻撃原理を理解した後、SQL インジェクション攻撃を防ぐ方法を見てみましょう。
magic_quotes_gpc = Onの場合のインジェクション攻撃
magic_quotes_gpc = On の場合、攻撃者は文字フィールドに対して SQL インジェクションを実行できません。だからといって安全というわけではありません。現時点では、SQL インジェクションは数値フィールドを通じて実行できます。
最新バージョンのMYSQL 5.xでは、データ型の入力が厳格化され、自動型変換がデフォルトでオフになっています。数値フィールドを引用符でマークされた文字タイプにすることはできません。言い換えれば、uid が数値であると仮定すると、以前の mysql バージョンでは、このようなステートメントは正当です:
コードをコピー | |
SELECT * FROM tbl_user WHERE uid="1";
|
コードをコピー | |||||||||||||||||||||||||||||||||
SELECT * FROM tbl_user WHERE uid=1;
|
コードは次のとおりです | コードをコピー |
} <フォームメソッド=ポストアクション=""> ユーザー ID: パスワード: |
上記のスクリプトでは、ユーザーはログインするためにユーザー ID とパスワードを入力する必要があります。通常のステートメントでは、ユーザーは 1001 と abc123 を入力し、送信された SQL ステートメントは次のとおりです:
コードは次のとおりです | コードをコピー |
SELECT * FROM tbl_users WHERE userid=1001 AND パスワード = 'abc123' LIMIT 0,1 |
攻撃者が「1001 OR 1 =1 # at userid」と入力した場合、挿入される SQL ステートメントは次のようになります。
コードをコピー | |
|
SQL インジェクションを防止 - mysql_real_escape_string() 関数を使用します
データベースオペレーションコードでこの関数 mysql_real_escape_string() を使用して、引用符などのコード内の特殊文字を除外します。例として:
コードをコピー | |||||||||||||||||
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ) " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password' ] )。 ?>
|
コードは次のとおりです | コードをコピー |
//接続 //データベースの選択 $q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['パスワード'] )、$database); ?>
|
php.iniのdisplay_errorsオプションはdisplay_errors = offに設定する必要があります。これにより、php スクリプトでエラーが発生した後は、Web ページにエラーが出力されなくなり、攻撃者による有用な情報の分析が防止されます。
mysql_query などの mysql 関数を呼び出すときは、mysql エラーが出力されないように、先頭に @ を追加する必要があります (@mysql_query(...))。攻撃者が有益な情報を分析できないようにする場合も同様です。さらに、一部のプログラマーは、開発時に mysql_query エラーが発生したときにエラーと SQL ステートメントを出力することに慣れています。例:
コードをコピー | |
if ( mysql_query($t_strSQL) ) { // 正しい取り扱い } それ以外 { echo "エラー! SQL ステートメント: $t_strSQL rn エラー メッセージ".mysql_query(); 終了します; } |
グローバル設定ファイル内:
コードをコピー | |
コードをコピー | |
{ // 正しい取り扱い } それ以外は { if (デバッグ_モード) echo "エラー! SQL ステートメント: $t_strSQL rnエラー メッセージ".mysql_query(); 終了します; } |