ホームページ >バックエンド開発 >PHPチュートリアル >PHP Web サイトでの一般的な攻撃手法
PHP Web サイト構築における一般的なセキュリティ脅威には、SQL インジェクション、GET および POST 変数の操作、バッファ オーバーフロー攻撃、クロスサイト スクリプティング攻撃、ブラウザ内データ操作、リモート フォーム送信などがあります。
SQL インジェクション攻撃では、ユーザーはフォームまたは GET クエリ文字列を操作してデータベース クエリに情報を追加します。
たとえば、単純なログイン データベースを想像してください。このデータベースの各レコードには、ユーザー名フィールドとパスワード フィールドがあります。ユーザーがログインできるようにするログイン フォームを作成します。
この問題の解決策は、PHP の組み込み mysql_real_escape_string() 関数をユーザー入力のラッパーとして使用することです。
この関数は文字列内の文字をエスケープし、文字列内でアポストロフィなどの特殊文字を渡すことを不可能にし、MySQL が特殊文字に基づいて動作できるようにします。リスト 7 はエスケープされたコードを示しています。
ユーザーが有効なパスワードを持っているからといって、そのユーザーがルールに従って行動するとは限りません。損害を引き起こす可能性は数多くあります。たとえば、アプリケーションでは、ユーザーが特別なコンテンツを表示できるようにする場合があります。
たとえば、template.php?pid=33 または template.php?pid=321。 URL の疑問符の後の部分はクエリ文字列と呼ばれます。クエリ文字列は URL に直接配置されるため、GET クエリ文字列とも呼ばれます。
ここで何か問題がありますか?
まず第一に、ブラウザからの GET 変数 pid は安全であることが暗黙的に信頼されています。
どうなるのでしょうか?
ほとんどのユーザーは、セマンティック攻撃を構築できるほど賢くありません。ただし、ブラウザの URL 場所フィールドに pid=33 があることに気付いた場合、問題が発生し始める可能性があります。
別の番号を入力した場合は問題ないかもしれませんが、SQL コマンドやファイル名 (/etc/passwd など) を入力したり、他のいたずらをしたりした場合は問題ありません。最大 3,000 文字の場合はどうなりますか?
この場合、ユーザー入力を信用しないという基本的なルールを思い出してください。
アプリケーション開発者は、template.php で受け入れられる個人識別子 (PID) は数値である必要があることを知っているため、PHP の is_numeric() 関数を使用して、数値以外の PID が受け入れられないようにできます。
必要なのは、strlen() を使用して、変数の長さがゼロでないかどうかを確認することだけです。そうである場合は、すべて数値の正規表現を使用して、データ要素が有効であることを確認します。 PID に文字、スラッシュ、ピリオド、または 16 進数に類似したものが含まれている場合、このルーチンはそれを捕捉し、ユーザーのアクティビティからページをブロックします。
バッファ オーバーフロー攻撃は、PHP アプリケーション (より正確には、Apache または基盤となるオペレーティング システム) のメモリ割り当てバッファをオーバーフローさせようとします。
Web アプリケーションを PHP などの高級言語で作成しているかもしれませんが、最終的には C を呼び出していることになります (Apache の場合)。ほとんどの低レベル言語と同様、C にはメモリ割り当てに関する厳密なルールがあります。
バッファ オーバーフロー攻撃は、大量のデータをバッファに送信し、データの一部を隣接するメモリ バッファにオーバーフローさせ、バッファを破壊したりロジックを書き換えたりする攻撃です。これにより、サービス拒否、データの破損、またはリモート サーバー上で悪意のあるコードの実行が発生する可能性があります。
バッファ オーバーフロー攻撃を防ぐ唯一の方法は、すべてのユーザー入力の長さをチェックすることです。
バッファ オーバーフロー攻撃は、数字や文字の長い文字列に限定されないことに注意してください。また、長い 16 進文字列 (xA3 や xFF のように見える) が表示されることもあります。
バッファ オーバーフロー攻撃の目的は、特定のバッファをフラッドし、悪意のあるコードや命令を次のバッファに配置し、それによってデータを破損したり、悪意のあるコードを実行したりすることであることに注意してください。
16 進数バッファーのオーバーフローに対処する最も簡単な方法は、入力が特定の長さを超えないようにすることです。
データベース内で長いエントリを許可するフォームのテキスト領域を扱っている場合、クライアント側でデータの長さを簡単に制限する方法はありません。データが PHP に到達したら、正規表現を使用して 16 進数のような文字列を消去できます。
クロスサイト スクリプティング (XSS) 攻撃では、悪意のあるユーザーが (または他のユーザー入力方法を通じて) 情報を入力することが多く、これらの入力によって悪意のあるクライアント側のタグが挿入されます。プロセスまたはデータベース内で。
たとえば、サイトに訪問者が名前、電子メール アドレス、簡単なメッセージを残せるシンプルなゲストブック プログラムがあるとします。
悪意のあるユーザーは、この機会を利用して、他のユーザーにとって不適切な画像や、ユーザーを別のサイトにリダイレクトする JavaScript など、短いメッセージ以外のものを挿入したり、Cookie 情報を盗んだりする可能性があります。
幸いなことに、PHP には、HTML タグで囲まれたコンテンツを削除できるstrip_tags() 関数が用意されています。また、strip_tags() 関数を使用すると、許可されたタグのリストを提供できます。
セキュリティの観点から、パブリックユーザー入力にstrip_tags()を使用することが必要です。フォームが保護領域 (コンテンツ管理システムなど) にあり、ユーザーがタスク (Web サイトの HTML コンテンツの作成など) を正しく実行することを信頼している場合、strip_tags() の使用は不要であり、生産性に影響を与える可能性があります。
もう 1 つの質問: 投稿やゲストエントリへのコメントなどのユーザー入力を受け入れ、この入力を他のユーザーに表示する必要がある場合は、応答を PHP の htmlspecialchars() 関数に入れる必要があります。
この関数は、アンパサンド、< および > 記号を HTML エンティティに変換します。たとえば、アンパサンド (&) は & になります。この場合、悪意のあるコンテンツがフロントエンドのstrip_tags()の処理を逃れたとしても、バックエンドのhtmlspecialchars()によって処理されます。
ユーザーがページ上のヘッダー要素やフォーム要素を改ざんできるタイプのブラウザー プラグインがあります。 Mozilla プラグインである Tamper Data を使用すると、多くの非表示のテキスト フィールドを持つ単純なフォームを簡単に操作して、PHP や MySQL に指示を送信できます。
ユーザーがフォームで「送信」をクリックする前に、データの改ざんを開始できます。フォームを送信すると、フォーム データ フィールドのリストが表示されます。
データの改ざんを使用すると、ブラウザーがフォームの送信を完了する前に、ユーザーがこのデータを改ざんできます。
このツールを防御する最も簡単な方法は、どのユーザーも Tamper Data (または同様のツール) を使用する可能性が高いと想定することです。
システムがフォームを処理するために必要な最小限の情報のみを提供し、フォームを専用のロジックに送信します。たとえば、登録フォームは登録ロジックにのみ送信する必要があります。
共通のフォーム処理関数を構築し、多くのページがこの共通ロジックを使用している場合はどうなるでしょうか?
フローを制御するために隠し変数を使用したらどうなるでしょうか?
たとえば、どのデータベーステーブルに書き込むか、またはどのファイルリポジトリを使用するかを隠しフォーム変数で指定できます。オプションは 4 つあります:
何も変更せず、システムに悪意のあるユーザーがいないことを密かに祈ります。
より安全な専用フォーム処理関数を使用し、非表示のフォーム変数の使用を避けるように関数を書き換えます。
md5() またはその他の暗号化メカニズムを使用して、隠しフォーム変数内のテーブル名またはその他の機密情報を暗号化します。 PHP 側でそれらを復号化することを忘れないでください。
略語やニックネームを使用して値の意味を曖昧にし、PHP フォーム処理関数でこれらの値を変換します。たとえば、users テーブルを参照したい場合は、u または任意の文字列 (u8y90×0jkL など) を使用して参照できます。
後の 2 つのオプションは完璧ではありませんが、ユーザーがミドルウェア ロジックやデータ モデルを簡単に推測するよりははるかに優れています。
Web の利点は、情報とサービスを共有できることです。欠点は、情報やサービスの共有です。何の躊躇もなく物事を行う人もいます。
フォームを例に挙げてみましょう。誰でも Web サイトにアクセスし、ブラウザ上で [ファイル] > [名前を付けて保存] を使用してフォームのローカル コピーを作成できます。次に、完全修飾 URL (formHandler.php ではなく、フォームはこのサイトにあるため http://www.yoursite.com/formHandler.php) を指すようにアクション パラメーターを変更し、必要な操作を行うことができます。変更を加えて [送信] をクリックすると、サーバーはこのフォーム データを法的な通信フローとして受信します。
まず、$_SERVER['HTTP_REFERER'] をチェックして、リクエストが自分のサーバーからのものであるかどうかを確認することを検討してください。この方法では、ほとんどの悪意のあるユーザーをブロックできますが、最も高度なハッカーをブロックすることはできません。これらの人々は、ヘッダー内の参照元情報を改ざんして、フォームのリモート コピーをサーバーから送信されたかのように見せかけるほど賢いのです。
リモート フォームの送信を処理するより良い方法は、一意の文字列またはタイムスタンプに基づいてトークンを生成し、このトークンをセッション変数とフォームに入れることです。フォームを送信した後、2 つのトークンが一致するかどうかを確認します。一致しない場合は、誰かがフォームのリモート コピーからデータを送信しようとしていることがわかります。
SQL インジェクションの問題を防ぐには、mysql_real_escape_string() を使用します。
正規表現と strlen() を使用して、GET データが改ざんされていないことを確認します。
正規表現と strlen() を使用して、ユーザーが送信したデータがメモリ バッファーをオーバーフローしないようにします。
strip_tags() と htmlspecialchars() を使用して、ユーザーが潜在的に有害な HTML タグを送信しないようにします。
Tamper Data などのツールによるシステムの侵害を防ぎます。
一意のトークンを使用して、ユーザーがリモートからサーバーにフォームを送信できないようにします。
関連する推奨事項:
PHP Web サイト開発におけるいくつかの一般的な攻撃手法を解決する
クロスサイト攻撃および xss 攻撃を防ぐための PHP 実装サンプル コード
以上がPHP Web サイトでの一般的な攻撃手法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。