ホームページ >バックエンド開発 >PHPチュートリアル >PHP で SQL インジェクション攻撃を防ぐ方法の紹介

PHP で SQL インジェクション攻撃を防ぐ方法の紹介

不言
不言転載
2018-11-24 15:17:362381ブラウズ

この記事は、PHP で SQL インジェクション攻撃を包括的にブロックする方法を紹介します。一定の参考価値があります。必要な友人は参照してください。お役に立てれば幸いです。助けてくれた。

攻撃動機にはさまざまな種類があると思われますが、一見したところ、さらに種類があるように見えます。これは、悪意のあるユーザーが複数のクエリを実行する方法を見つけた場合に当てはまります。

スクリプトが SELECT 命令を実行している場合、攻撃者は、以下に示すように、「1=1」などの条件を WHERE 句に挿入することで、テーブル内のレコードの各行を強制的に表示できます。 (挿入された部分が太字で示されている):

SELECT * FROM wines WHERE variety = 'lagrein' OR 1=1;'

前にコメントしたように、これはテーブルの一般的な構造を明らかにするため、それ自体が有益な情報である可能性があります (これは通常のレコードでは達成できません) )、および機密情報が含まれている可能性がある記録。

更新コマンドは、より直接的な脅威となる可能性があります。 SET 句に他の特性を組み込むことにより、攻撃者は、次の例 (挿入された部分が太字で示されています) のように、更新中のレコード内の任意のフィールドを変更できます。更新命令の WHERE 句に 1=1 などの true 条件を追加します。この変更範囲は、次の例のようにすべてのレコードに拡張できます (挿入された部分が太字で示されています):

UPDATE wines SET type='red','vintage'='9999' WHERE variety = 'lagrein'

おそらく最も危険なコマンドは DELETE であることは想像に難くありません。注入手法は、これまでに説明したものと同じです。次の例のように、WHERE 句を変更して影響を受けるレコードの範囲を拡張します (注入された部分が太字で表示されています):

UPDATE wines SET type='red','vintage'='9999 WHERE variety = 'lagrein' OR 1=1;'

複数のクエリ インジェクション

複数のクエリ インジェクションは、単一のクエリに複数の破壊的な命令が含まれることを可能にするため、攻撃者が引き起こす可能性のある潜在的な被害を増大させます。 MySQL データベースを使用する場合、攻撃者はクエリに予期しない停止文字を挿入することでこれを簡単に達成できます。挿入された引用符 (一重または二重) が目的の変数の終わりを示し、コマンドをセミコロンで終了します。ここで、停止された元のコマンドの最後に追加の攻撃コマンドを追加できるようになります。最終的な破壊的なクエリは次のようになります:

DELETE FROM wines WHERE variety = 'lagrein' OR 1=1;'

このインジェクションは新しいユーザー BadGuy を作成し、それにネットワーク権限 (すべてのテーブルに対するすべての権限) を与えます。さらに、「不気味な」パスワードが追加されます。この単純な SELECT 文に。前の記事のアドバイスに従ってプロセス ユーザーの権限を厳しく制限した場合、Web サーバー デーモンには取り消した GRANT 権限がなくなっているため、これは機能しません。しかし理論的には、このような攻撃により、BadGuy はデータベースに対してやりたいことを何でもできるようになる可能性があります。

このようなマルチクエリが MySQL サーバーによって処理されるかどうかについては、結論は一意ではありません。理由の一部は MySQL のバージョンの違いに起因する可能性がありますが、ほとんどの原因は複数のクエリの存在方法にあります。 MySQL の監視プログラムでは、このようなクエリを完全に許可します。一般的に使用される MySQL GUI-phpMyAdmin は、最後のクエリの前に以前のすべてのコンテンツをコピーし、これのみを実行します。

ただし、インジェクション コンテキスト内のほとんどの複数のクエリは、PHP の mysql 拡張機能によって管理されます。幸いなことに、デフォルトでは、クエリ内で複数の命令を実行することはできません。2 つの命令 (上記のインジェクションなど) を実行しようとすると、エラーが設定されず、情報も出力されません。この場合、PHP はデフォルトの動作を「定期的に」実装するだけですが、ほとんどの単純なインジェクション攻撃から実際に保護できます。

PHP5 の新しい mysqli 拡張機能 (http://php.net/mysqli を参照) は、mysql と同様に、本質的に複数のクエリをサポートしませんが、複数のクエリの完了をサポートする mysqli_multi_query() 関数を提供します。 - 本当にそうしたいのなら。

ただし、PHP5 にバンドルされている埋め込み可能な SQL データベース エンジンである SQLite (http://sqlite.org/ および http://php.net/sqlite を参照) の状況は、その使いやすさのせいでさらに悲惨です。このアプリケーションは多くのユーザーの注目を集めています。場合によっては、データベースがバッチ クエリ、特にバッチ INSERT ステートメント処理を最適化でき、非常に効率的であるため、SQLite ではそのような複数命令クエリがデフォルトで許可されます。


ただし、クエリの結果がスクリプトで使用される場合 (たとえば、レコードを取得するために SELECT 文を使用する場合)、sqlite_query() 関数では複数のクエリの実行は許可されません。

3. INVISION Power BOARD SQL インジェクションの脆弱性

Invision Power Board はよく知られたフォーラム システムです。 2005 年 5 月 6 日、ログイン コードに SQL インジェクションの脆弱性が発見されました。これは、GulfTech Security Research の James Bercegay によって発見されました。

このログイン クエリは次のとおりです:

SELECT 
 FROM wines WHERE variety = 'lagrein';GRANT ALL ON 
.* TO 'BadGuy@%' IDENTIFIED BY 'gotcha';'

一方、メンバー ID 変数 $mid とパスワード ID 変数 $pid は、次の 2 行のコードを使用して my_cookie() 関数から取得されます。 :

$DB->query("SELECT * FROM ibf_members WHERE id=$mid AND password='$pid'");

ここで、my_cookie() 関数は次の文を使用して Cookie から要求された変数を取得します:

return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);

【留意】从该cookie回来的值底子没有被处理。虽然$mid在运用于查询之前被强制转换成一个整数,可是$pid却保持不变。因而,它很容易遭受咱们前面所评论的注入类型的进犯。

因而,经过以如下方法修正my_cookie()函数,这种软弱性就会露出出来:

if ( ! in_array( $name,array('topicsread', 'forum_read','collapseprefs') ) )
{
return $this->
clean_value(urldecode($_cookie[$ibforums->vars['cookie_id'].$name]));
}
else
{
return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);
}

经过这样的改正之后,其间的要害变量在"经过"全局clean_value()函数后被回来,而其它变量却未进行检查。
现在,已然咱们大致了解了什么是SQL注入,它的注入原理以及这种注入的软弱程度,那么接下来,让咱们探讨如何有用地防备它。幸亏,PHP为咱们供给了丰厚的资源,因而咱们有充沛的信心预言,一个经细心地彻底地运用咱们所引荐的技能构建的应用程序将会从你的脚本中底子上消除任何或许性的SQL注入-经过在它或许形成任何损坏之前"整理"你的用户的数据来完成。

以上がPHP で SQL インジェクション攻撃を防ぐ方法の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。