ホームページ >バックエンド開発 >PHPチュートリアル >PHP アプリケーションの保護、PHP アプリケーションの保護_PHP チュートリアル

PHP アプリケーションの保護、PHP アプリケーションの保護_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:14:36931ブラウズ

PHP アプリケーションの保護、PHP アプリケーションの保護

始める前に
このチュートリアルでは、独自の PHP Web アプリケーションにセキュリティを追加する方法を学習します。このチュートリアルでは、PHP Web アプリケーションの作成経験が少なくとも 1 年あることを前提としているため、PHP 言語の基本的な知識 (規則または構文) についてはここでは説明しません。目的は、構築する Web アプリケーションを保護する方法を理解していただくことです。

目標

このチュートリアルでは、SQL インジェクション、GET および POST 変数の操作、バッファ オーバーフロー攻撃、クロスサイト スクリプティング攻撃、ブラウザ内データ操作、リモート フォーム送信などの最も一般的なセキュリティ脅威から保護する方法について説明します。

前提条件

このチュートリアルは、少なくとも 1 年のプログラミング経験を持つ PHP 開発者を対象に書かれています。 PHP の構文と規則については理解する必要がありますが、ここでは説明しません。ここで説明するルールの多くは他の言語や環境にも適用されるため、Ruby、Python、Perl などの他の言語を使用した経験のある開発者もこのチュートリアルから恩恵を受けるでしょう。

セキュリティの簡単な紹介

Web アプリケーションの最も重要な部分は何ですか?誰が質問に答えるかによって、この質問に対する答えは異なる場合があります。ビジネスマンは信頼性と拡張性を必要としています。 IT サポート チームは、堅牢で保守可能なコードを必要としています。エンドユーザーは、タスクを実行する際に美しいユーザー インターフェイスと高いパフォーマンスを必要とします。しかし、答えが「セキュリティ」であれば、それが Web アプリケーションにとって重要であることに誰もが同意するでしょう。
しかし、ほとんどの議論はここで終わります。セキュリティはプロジェクトのチェックリストに含まれていますが、多くの場合、プロジェクトが納品されるまで対処されません。このアプローチを採用している Web アプリケーション プロジェクトの数は驚異的です。開発者は何か月もかけて取り組み、最後にセキュリティ機能を追加して、Web アプリケーションを一般公開できるようにしました。
セキュリティ機能が追加される前にコードが検査され、単体テストされ、より大きなフレームワークに統合されているため、結果は混乱したり、再作業が必要になったりすることがよくあります。セキュリティを追加すると、主要なコンポーネントが動作しなくなる場合があります。セキュリティを統合すると、スムーズな (ただし安全ではない) プロセスに余分な負担やステップが追加されます。
このチュートリアルは、PHP Web アプリケーションにセキュリティを統合するための優れた方法を提供します。ここでは、いくつかの一般的なセキュリティのトピックについて説明し、その後、主要なセキュリティの脆弱性とその解決方法について詳しく説明します。このチュートリアルを完了すると、セキュリティについてより深く理解できるようになります。
トピックには以下が含まれます:
SQL インジェクション攻撃
GET 文字列の操作
バッファ オーバーフロー攻撃
クロスサイト スクリプティング攻撃 (XSS)
ブラウザ内データ操作
リモート フォーム送信

Web セキュリティ 101

セキュリティの実装についての議論詳細については、Web アプリケーションのセキュリティを高レベルの観点から議論するのが最善です。このセクションでは、作成する Web アプリケーションの種類に関係なく、心に留めておくべきセキュリティ哲学の基本原則をいくつか紹介します。これらのアイデアの中には、Chris Shiflett (PHP セキュリティーに関する著書は貴重な宝庫です) から得たもの、Simson Garfinkel (「参考文献」を参照) から得たもの、そして長年蓄積された知識から得たものもあります。
ルール 1: 外部データや入力を決して信頼しない
Web アプリケーションのセキュリティについて最初に認識しなければならないことは、外部データは信頼すべきではないということです。外部データには、プログラマによって PHP コードに直接入力されないデータが含まれます。他のソースからのデータ (GET 変数、フォーム POST、データベース、構成ファイル、セッション変数、Cookie など) は、セキュリティを確保するための手順が講じられるまで信頼できません。
たとえば、次のデータ要素は PHP で設定されているため安全であると考えられます。
リスト 1. 安全で完璧なコード

[php]$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername); [/php]
ただし、次のデータ要素にはすべて欠陥があります。 、 リスト 2. 安全でない欠陥のあるコード

[PHP] $ myusername = $ _post ['username'] // 汚染されています
$ arrayusers = Array ($ myusername, 'tom', 'tommy'); !
define("GREETING", 'hello there' . $myUsername); //tainted! [/php]
最初の変数 $myUsername が間違っているのはなぜですか?これはフォーム POST から直接取得されるためです。ユーザーはこの入力フィールドに任意の文字列を入力できます。これには、ファイルを駆除したり、以前にアップロードしたファイルを実行したりする悪意のあるコマンドも含まれます。 「A ~ Z の文字のみを受け入れるクライアント側 (JavaScript) フォーム検証スクリプトを使用すれば、この危険を回避できないのですか?」と疑問に思われるかもしれません。はい、これは常に有益なステップですが、後で説明するように、誰でもあらゆるフォームを自分のマシンにダウンロードし、変更して、必要なものを再送信できます。
解決策は簡単です。サニタイズ コードは $_POST['username'] で実行する必要があります。これを行わないと、(配列や定数などで) $myUsername を使用するたびに、これらのオブジェクトが汚染される危険があります。
ユーザー入力をサニタイズする簡単な方法は、正規表現を使用して処理することです。この例では、文字のみが受け入れられることが想定されています。文字列を特定の文字数に制限したり、すべての文字を小文字にすることを要求したりすることも良いアイデアかもしれません。リスト 3. ユーザー入力が安全になります。 ; //clean!
define("GREETING", 'hello there' . $myUsername); //clean!
function cleanInput($input){
$clean = strto lower($input) );
$clean = preg_replace(" /[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}[/php]
ルール 2: セキュリティを困難にするものを無効にする PHP セットアップの実装
ユーザー入力が信頼できないことがわかったので、マシン上での PHP の構成方法も信頼すべきではないことも理解する必要があります。たとえば、register_globals が無効になっていることを確認してください。 register_globals が有効な場合、$variable を使用して GET または POST 文字列を同じ名前に置き換えるなどの不注意な行為が可能になります。この設定を無効にすると、PHP は正しい名前空間の正しい変数を参照するように強制します。フォーム POST から変数を使用するには、$_POST['variable'] を引用符で囲む必要があります。こうすることで、この特定の変数を Cookie、セッション、または GET 変数と間違えることがなくなります。
2 番目に確認する設定は、エラー報告レベルです。開発中はできるだけ多くのエラー レポートを取得したいと考えますが、プロジェクトを納品するときは、エラーを画面に表示するのではなくログ ファイルに記録したいと考えます。なぜ?悪意のあるハッカーは、エラー報告情報 (SQL エラーなど) を使用して、アプリケーションが何を行っているかを推測する可能性があるためです。この種の偵察は、ハッカーがアプリケーションに侵入するのに役立つ可能性があります。この脆弱性を解決するには、php.ini ファイルを編集して error_log エントリの適切な保存先を指定し、display_errors を Off に設定します。

ルール 3: 理解できない場合、保護することはできません
一部の開発者は、奇妙な構文を使用したり、ステートメントを非常に厳密に編成して、短くても曖昧なコードを形成します。このアプローチは効率的かもしれませんが、コードが何をしているのかを理解していないと、コードを保護する方法を決定できません。
たとえば、以下の 2 つのコードのうちどれが好きですか?リスト 4. コードを保護しやすくする

$input = ”;
if (isset($_POST['ユーザー名'])){
$input = $_POST['ユーザー名'];
}else{
$ input = ”;
}[/php]
2 番目の明確なコード スニペットでは、$input に欠陥があり、安全に処理する前にクリーンアップする必要があることが簡単にわかります
ルール 4: 「多層防御」新しい魔法の武器
このチュートリアルでは、フォームを処理する PHP コードで必要な措置を講じながらオンライン フォームを保護する方法を説明する例を示します。同様に、GET 変数が完全に数値であることを確認するために PHP 正規表現を使用する場合でも、 SQL クエリがエスケープされたユーザー入力を使用するようにするための措置を講じることもできます
多層防御は良いアイデアであるだけでなく、深刻な問題に巻き込まれないようにするための手段です
基本的なルールについて説明したので、見てみましょう。最初の脅威: SQL インジェクション攻撃

SQL インジェクション攻撃の防止

。SQL インジェクション攻撃では、ユーザーはフォームまたは GET クエリ文字列を操作してデータベース クエリに情報を追加します。たとえば、単純なログイン データベースについて考えてみましょう。このデータベースには、ユーザー名フィールドとパスワードフィールドがあります。ユーザーがログインできるようにするログインフォームを作成します。
リスト 5. 単純なログインフォーム
[php]
Login< ;/title><br></head> <br><body><br><form action=”verify.php” method=”post”><br><p><label for='user'>ユーザー名< /label><br><input type=' text' name='user' id='user'/><br></p><br><p><label for='pw'>パスワード</label> ;<br /><input type='password' name='pw' id='pw'/><br></p><br><p><input type='submit' value='login'/> </p><br></form> ;<br /></body><br></html>[/php] <br>このフォームはユーザー名とパスワードのユーザー入力を受け入れ、そのユーザー入力を verify.php というファイルに送信します。このファイルでは、PHP は以下に示すようにログイン フォームからのデータを処理します。 <br>リスト 6. 安全でない PHP フォーム処理コード <br> 'user'];<br>$pw = $_POST['pw'];<br>$sql = "選択count(*) as ctr from users where<br>username='".$username."' and password='". $ pw."' limit 1";<br><br>$result = mysql_query($sql);<br>while ($ data = mysql_fetch_object($result)){<br>if ($data->ctr == 1){<br> //アプリケーションに入っても大丈夫です!<br> $okay = 1;<br>}<br>}<br>if ($okay ){<br>$_SESSION['loginokay'] = true;<br>header("index.php");<br>}else{ <br>header("login.php");<br>}<br>?> [/php]<br>このコード大丈夫そうですよね?このようなコードは、世界中の数百 (数千ではないにしても) の PHP/MySQL サイトで使用されています。どうしたの? 「ユーザー入力は信頼できない」ということを覚えておいてください。ここではユーザーからの情報はエスケープされないため、アプリケーションは脆弱なままになります。具体的には、あらゆる種類の SQL インジェクション攻撃が可能です。 <br>たとえば、ユーザーがユーザー名として foo を入力し、パスワードとして ' または '1'='1 を入力すると、実際には次の文字列が PHP に渡され、クエリが MySQL に渡されます。 <br>$sql = “select count( *) as ctr from users where username='foo' and passwd=” or '1'='1' limit 1''; このクエリは常に 1 のカウントを返すため、PHP はパスワード文字を挿入することでアクセスを許可します。文字列の末尾に悪意のある SQL が含まれている場合、ハッカーは正規のユーザーになりすますことができます。この問題の解決策は、PHP の組み込み mysql_real_escape_string() 関数をユーザー入力のラッパーとして使用することです。これにより、文字がエスケープされなくなります。 <br>リスト 7. 安全な PHP フォーム処理コード <br> [php ]<?php<br />$okay = 0;<br />$username = $_POST['user '];<br />$pw = $_POST['pw'];<br />$sql = “<br /> username='".mysql_real_escape_string($username)."'<br /> およびpassword='"のユーザーからctrとしてcount(*)を選択します。 .mysql_real_escape_string($pw)."' 制限 1'';<br /> <br />$result = mysql_query($sql);<br />while ($data = mysql_fetch_object($result)){<br />if ($data->ctr == 1) {<br /> //アプリケーションに入っても問題ありません!<br /> $okay = 1;<br />}<br />}<br />if ($okay){ <br />$_SESSION['loginokay'] = true;<br />header("index.php") ;<br />}else{<br />header("login.php");<br />}<br />?>[/php]<br><br>mysql_real_escape_string( ) は、ユーザー入力への悪意のある SQL インジェクションを回避するためにユーザー入力のラッパーとして機能します。ユーザーが SQL インジェクション経由で不正なパスワードを渡そうとすると、次のクエリがデータベースに渡されます: <br>select count(*) as ctr from users where <br>username='foo' and passwd='' or '1'='1 「制限 1」 <br>そのようなパスワードに一致するものはデータベース内にありません。たった 1 つの簡単な手順で、Web アプリケーションの大きな穴を塞ぐことができました。ここでの経験則は、SQL クエリのユーザー入力は常にエスケープする必要があるということです。 <br>ただし、塞がなければならないセキュリティ ホールがまだいくつかあります。次の項目は、GET 変数を操作することです。 <br><br>ユーザーが変数を操作できないようにする<br><br> 前のセクションでは、ユーザーが不正なパスワードでログインできないようにしました。賢明な方であれば、学んだことを応用して、SQL ステートメントへのすべてのユーザー入力が確実にエスケープされるようにする必要があります。 <br>ただし、ユーザーは安全にログインしています。ユーザーが有効なパスワードを持っているからといって、そのユーザーがルールに従って行動するわけではありません。ユーザーが損害を与える可能性は数多くあります。たとえば、アプリケーションでは、ユーザーが特別なコンテンツを表示できるようにする場合があります。すべてのリンクは、template.php?pid=33 や template.php?pid=321 などの場所を指します。 URL の疑問符の後の部分はクエリ文字列と呼ばれます。クエリ文字列は URL に直接配置されるため、GET クエリ文字列とも呼ばれます。 <br>PHP では、 register_globals が無効になっている場合、この文字列には $_GET['pid'] でアクセスできます。 template.php ページでは、リスト 8 と同様のことを行うことができます。例文リスト 8. 例 template.php<br> <br> <br> [php] & lt ;? pHP<br> $ pid = $ _get ['pid'] <br> // 画像クラスページのオブジェクトを作成します<br>$obj = new Page;<br>$content = $obj->fetchPage($pid);<br>//これで、ページを表示する一連の PHP が完成しました<br>//…<br>//…<br>?> [/ php]<br>ここで何か問題がありますか?まず、ブラウザからの GET 変数 pid は安全であると暗黙的に信頼されます。何が起こるか?ほとんどのユーザーはセマンティック攻撃を構築できるほど賢くありません。ただし、ブラウザの URL 場所フィールドに pid=33 があることに気付いた場合、問題が発生し始める可能性があります。別の数字を入力した場合はおそらく問題ありませんが、SQL コマンドやファイル名 (/etc/passwd など) など、他の何かを入力した場合、または 3,000 と入力するなどのトリックがあった場合は、文字の値、どうなりますか? <br>この場合、ユーザー入力を信用しないという基本的なルールを思い出してください。アプリケーション開発者は、template.php で受け入れられる個人識別子 (PID) が数値である必要があることを知っているため、以下に示すように、PHP の is_numeric() 関数を使用して、数値以外の PID が受け入れられないようにできます。 GET 変数を制限する<br> new Page;<br>$content = $obj->fetchPage($pid);<br>//これで、ページを表示する一連の PHP が完成しました <br>//…<br>//… <br>}その他{ <br>// is_numeric() テストに合格しませんでした。他のことをしてください!<br>}?> [/php]<br> このメソッドは有効のようですが、次の入力は is_numeric() チェックに簡単に合格できます: <br>100 (有効) <br>100.1 (小数点以下の桁があってはなりません) <br>+0123.45e6 (科学的表記 – 悪い) <br>0xff33669f (16 進数 – 危険! 危険!) <br> では、セキュリティを重視する PHP 開発者は何をすべきでしょうか?長年の経験から、以下に示すように、正規表現を使用して GET 変数全体が数値で構成されていることを確認するのが最善の方法であることがわかっています。 <br> リスト 10. 正規表現を使用して GET 変数を制限する <br> [php] & lt;? <br> $ pid = $_GET['pid'];<br><b><br>if (strlen($pid)){<br>if (!ereg("^[0-9]+$",$pid)){<br> //ログアウトするか、ホームページに送り返すなど、適切な処理をしてください<br>}<br>}else{<br>//$pid が空なので、ホームページに送り返してください<br>}<br></b><br>/ /架空のクラス Page のオブジェクトを作成します。これで<br>//邪悪なユーザー入力から適度に保護されます<br>$obj = new Page;<br>$content = $obj->fetchPage($pid);<br>//そして今ページ <br>//…<br>//…<br>?>[/php]<br> を表示する一連の PHP があります。必要なのは、strlen() を使用して変数の長さがゼロ以外かどうかを確認することだけです。その場合は、完全な数値の正規表現を使用して、データ要素が有効であることを確認します。 PID に文字、スラッシュ、ピリオド、または 16 進数に類似したものが含まれている場合、このルーチンはそれを捕捉し、ユーザーのアクティビティからページをブロックします。 Page クラスの舞台裏を見ると、以下に示すように、セキュリティを意識した PHP 開発者がユーザー入力 $pid をエスケープし、それによって fetchPage() メソッドを保護していることがわかります。脱出方法<br> <br> ”.mysql_real_escape_string($pid).”'”;<br> //etc, etc….<br><br>}<br>}<br>?> [/php]<br>私たちは、 PID は数値です。なぜエスケープする必要があるのですか?」 fetchPage() メソッドがどれだけ多くの異なるコンテキストや状況で使用されるかわからないからです。このメソッドが呼び出されるすべての場所で保護を提供する必要があり、メソッド内でのエスケープは多層防御の意味を具体化します。 <br>ユーザーがバッファ オーバーフロー攻撃を開始しようとして、最大 1000 文字などの非常に長い値を入力しようとするとどうなりますか?次のセクションでこれについて詳しく説明しますが、ここでは別のチェックを追加して、入力 PID が正しい長さであることを確認できます。データベースの pid フィールドの最大長は 5 桁であることがわかっているため、次のチェックを追加できます。 <br>リスト 12. 正規表現と長さチェックを使用して GET 変数を制限する <br> <br>[php]<?php<br />$pid = $_GET['pid'];<br />if (strlen($pid)){<br />if (! ereg ("^[0-9]+$",$pid) && strlen($pid) > 5){<br /> //ログ記録など、適切な処理を行います <br />それらを送信するか、ホームページに送り返すか<br />}<br />}else{<br />//$pid が空なので、ホームページに送り返す<br />}<br />//架空のクラス Page のオブジェクトを作成します。これは今です<br />/ /悪意のあるユーザー入力からさらに保護されます<br />$obj = new Page;<br />$content = $obj->fetchPage($pid);<br>//これで、ページを表示する一連の PHP が完成しました <br>//…… <br>//…<br>?> [/php]<br> 現在、データベース アプリケーションに 5,000 桁の値を詰め込むことは誰にもできません (少なくとも GET 文字列が関係する場合はそうではありません)。アプリケーションに侵入しようとしてイライラしているハッカーが歯ぎしりしているところを想像してみてください。また、エラー報告がオフになっているため、ハッカーによる偵察が困難になります。 <br><br>バッファ オーバーフロー攻撃 <br><br>バッファ オーバーフロー攻撃 PHP アプリケーション (より正確には、Apache または基盤となるオペレーティング システム) でメモリ割り当てバッファをオーバーフローさせようとする試み。 Web アプリケーションを PHP などの高級言語で作成している可能性がありますが、最終的には C を呼び出していることに注意してください (Apache の場合)。ほとんどの低レベル言語と同様、C にはメモリ割り当てに関する厳密なルールがあります。 <br>バッファ オーバーフロー攻撃は、大量のデータをバッファに送信し、データの一部を隣接するメモリ バッファにオーバーフローさせ、バッファを破壊したりロジックを書き換えたりします。これにより、サービス拒否、データの破損、またはリモート サーバー上で悪意のあるコードの実行が発生する可能性があります。 <br>バッファ オーバーフロー攻撃を防ぐ唯一の方法は、すべてのユーザー入力の長さをチェックすることです。たとえば、ユーザー名を必要とするフォーム要素がある場合は、このフィールドに値 40 の maxlength 属性を追加し、バックエンドで substr() を使用してチェックします。リスト 13 に、フォームと PHP コードの簡単な例を示します。 <br>リスト13.ユーザー入力の長さをチェック、40);<br>//処理を続行する…。 ?>” Method=”post”><br> <p><label for=”name”>名前</label><br><input type=”text” name=<br />”name” id=”name ” size=”20″ maxlength=”40″/ ></p><br><p><input type=”submit” name=”submit” value=”go”/></p> <br></form>[/php]<br><br> なぜ maxlength 属性を指定し、バックエンドで substr() チェックを行うのでしょうか?多層防御は常に有効だからです。ブラウザーは、PHP や MySQL が安全に処理できない非常に長い文字列 (誰かが最大 1,000 文字の長さの名前を入力しようとしているところを想像してください) をユーザーが入力することを防ぎ、バックエンド PHP チェックにより、誰もフォーム データをリモートまたはブラウザーで操作していないことを確認します。 。 <br>ご覧のとおり、このアプローチは、前のセクションで strlen() を使用して GET 変数 pid の長さをチェックするのと似ています。この例では、5 桁を超える入力値は無視されますが、以下に示すように、値は適切な長さに簡単に切り詰められます。 php<br>$pid = $_GET['pid'];<br>if (strlen($pid)){<br>if (!ereg("^[0-9]+$",$pid)){<br> / /if non数値の $pid、ホームページに送り返す<br>}<br>}else{<br>//$pid が空なので、ホームページに送り返す<br>}<br>//数値の pid がありますが、長すぎる可能性がありますので、確認してみましょう<br>if (strlen($pid)>5){<br> $pid = substr($pid,0,5);<br>}<br>//架空のクラス Page のオブジェクトを作成します。これは現在 <br>//悪意のあるユーザー入力からさらに保護されます<br>$obj = new Page;<br>$content = $obj->fetchPage($pid);<br>//これで、ページを表示する一連の PHP が完成しました <br>// …<br>/ /…<br>?>[/php]<br><br>バッファ オーバーフロー攻撃は、数字や文字の長い文字列に限定されないことに注意してください。また、長い 16 進文字列 (xA3 や xFF のように見える) が表示されることもあります。バッファ オーバーフロー攻撃の目的は、特定のバッファをフラッディングし、悪意のあるコードや命令を次のバッファに配置し、それによってデータを破損したり、悪意のあるコードを実行したりすることであることに注意してください。 16 進バッファ オーバーフローに対処する最も簡単な方法は、入力が特定の長さを超えないようにすることです。 <br>データベース内で長いエントリを許可するフォームのテキスト領域を扱っている場合、クライアント側でデータの長さを簡単に制限する方法はありません。データが PHP に到達したら、正規表現を使用して 16 進数のような文字列を消去できます。 <br>リスト 15. 16 進文字列の防止 <br>if ($_POST['submit'] == "go"){<br>$name = substr($_POST['name'],0,40);<br>//潜在的な 16 進文字をすべて削除します<br>$name = cleanHex( $name);<br>//処理を続行….<br>}<br>function cleanHex($input){<br>$clean = preg_replace(”![][xX]([A-Fa-f0-9]{1,3}) !”, “”,$input);<br>return $clean;<br>}<br>?><br><form action=”<?php echo $_SERVER['PHP_SELF'];?>” ><br><p><label for=”name”>名前</label><br><input type=”text” name=”name” id=”name” size=”20″ maxlength=”40 ''/></p><br><p><input type=”submit” name=”submit” value=”go”/></p><br></form>[/php] <br><br>この一連の操作は少し厳しすぎると感じるかもしれません。結局のところ、16 進文字列には、外国語で文字を印刷するなど、正当な用途があります。 16 進正規表現をどのように展開するかはあなた次第です。より良い戦略は、1 行に 16 進文字列が多すぎる場合、または文字列が特定の文字数 (128 や 255 など) を超える場合にのみ、16 進文字列を削除することです。 <br><br>クロスサイト スクリプティング攻撃<br><br> クロスサイト スクリプティング (XSS) 攻撃では、多くの場合、悪意のあるユーザーがフォーム (または他のユーザー入力方法を通じて) に情報を入力し、プロセスやプロセスに悪意のあるクライアント側のタグを挿入します。データベース。たとえば、サイトに訪問者が名前、電子メール アドレス、簡単なメッセージを残せる簡単なゲストブック プログラムがあるとします。悪意のあるユーザーはこの機会を利用して、他のユーザーにとって不適切な画像や、ユーザーを別のサイトにリダイレクトする JavaScript など、短いメッセージ以外のものを挿入したり、Cookie 情報を盗んだりする可能性があります。 <br>幸いなことに、PHP には、HTML タグで囲まれたコンテンツを削除できるstrip_tags() 関数が用意されています。また、strip_tags() 関数を使用すると、<b> や <i> など、許可されるタグのリストを提供できます。 <br>リスト 16 は、前の例を基にした例を示しています。用户 リスト 16. ユーザー入力から HTML マークをクリアします <br> <br> [php] & lt ;? php<br>if ($ _post ['submit'] == "go") {<br> //strip_tags<br> $ name =trip_tags ($ _ post [ 'name']);<br>$name = substr($name,0,40);<br>//潜在的な 16 進文字をすべて削除します<br>$name = cleanHex($name);<br>//処理を続行します….<br> }<br>function cleanHex($input){<br>$clean = preg_replace<br>("![][xX]([A-Fa-f0-9]{1,3})!", "",$input);<br> return $clean ;<br>}<br>?><br><form action=<br />“<?php echo $_SERVER['PHP_SELF'];?>” method=”post”><br><p><label for=” name”>名前</label><br><input type=<br />”text” name=”name” id=”name” size=”20″ maxlength=”40″/></p> <br>< p<input type=”submit” name=”submit” value=”go”/></p><br></form>[/php] <br>セキュリティの観点から、一般ユーザー向けinput ストリップタグ()を使用する必要があります。フォームが保護領域 (コンテンツ管理システムなど) にあり、ユーザーがタスク (Web サイトの HTML コンテンツの作成など) を正しく実行することを信頼している場合、strip_tags() の使用は不要であり、生産性に影響を与える可能性があります。 <br>もう 1 つの質問: 投稿やゲスト登録エントリに対するコメントなどのユーザー入力を受け入れ、この入力を他のユーザーに表示する必要がある場合は、必ず応答を PHP の htmlspecialchars() 関数に入れてください。この関数は、アンパサンド、< > 記号を HTML エンティティに変換します。たとえば、アンパサンド (&) は & になります。この場合、悪意のあるコンテンツがフロントエンドのstrip_tags()の処理を逃れたとしても、バックエンドのhtmlspecialchars()によって処理されます。 <br><br>ブラウザ内データ操作<br><br> ユーザーがページ上のヘッダー要素やフォーム要素を改ざんできるようにするブラウザー プラグインの一種があります。 Mozilla プラグインである Tamper Data を使用すると、多くの非表示のテキスト フィールドを持つ単純なフォームを簡単に操作して、PHP や MySQL に指示を送信できます。 <br>ユーザーがフォームで「送信」をクリックする前に、データ改ざんを開始できます。フォームを送信すると、フォーム データ フィールドのリストが表示されます。データの改ざんを使用すると、ブラウザーがフォームの送信を完了する前に、ユーザーがこのデータを改ざんできます。 <br>前に作成した例に戻りましょう。文字列の長さがチェックされ、HTML タグが削除され、16 進文字が削除されました。ただし、以下に示すように、いくつかの非表示のテキスト フィールドが追加されます。 <br>リスト 17. 非表示の変数<br>                   <br>[php]<?php<br />if ($_POST['submit'] == “go”){<br />//strip_tags<br />$name =trip_tags($_POST['name']);<br />$name = substr( $name,0,40);<br />//潜在的な 16 進文字をすべて削除します<br />$name = cleanHex($name);<br />//処理を続行します….<br />}<br />function cleanHex($input){<br />$clean = <br />preg_replace ("![][xX]([A-Fa-f0-9]{1,3})!", "",$input);<br />return $clean;<br />}<br />?><br><フォームアクション=<br />”<?php echo $_SERVER['PHP_SELF'];?>” Method=”post”><br><p><label for=”name”>名前</label><br><input type=<br />”text” name=”name” id=”name” size=” 20″ maxlength=”40″/></p><br><input type=”hidden” name=”table” value=”users”/><br /><input type=”hidden” name=”action ” value=”create”/><br><input type=”hidden” name=”status” value=”live”/><br><p><input type=”submit” name=”submit” value =”go”/></p><br></form> <br>[/php]<br>注意、変更量の 1 つは表名: users です。また、create のアクション フィールドも表示されます。基本的な SQL プロセスのみがあれば、これらのコマンドが中間コンポーネントを制御している可能性があることを確認できます。図 1 は、データの改ざんによって提供される破壊の範囲を示しています。 HTTP ブロックと Cookie の許可も許可されています。たとえば、一般的なテーブル処理関数が確立されている場合、多くのセクションでこの関数が使用されます。逻辑、このアクションは、ストリーム方向を制御するために使用する場合、たとえば、特定のデータ テーブルを指定するか、特定のファイルを使用することができます。 4 つの選択肢があります。何でも东西、暗自<br> <br> 再書き込み機能は、より安全な専用の表の処理関数を使用し、表の名前やその他の機密情報の使用を回避します。これらの値は、PHP エンドでの変換を忘れる必要はありません。これらの値は、ユーザーがテーブルを参照する場合、u またはその他の値を使用して PHP の処理関数で再度変換できます。 <br> 後の 2 つの選択肢は完璧ではありませんが、ユーザーが中間コンポーネントやデータ モデルを即座に取り出すよりも、より多くのものが得られることが望ましいです。問題は?够Web ステーションにアクセスし、ブラウザ上のファイルを使用します。その後、アクション パラメータを変更して、完全に限定された URL (表単位のため、formHandler.php ではなく、<br>http://www.yoursite.com/formHandler.php<img id="aimg_l1bkb" class="zoom" src="http://www.bkjia.com/uploads/allimg/141111/161F4I22-0.jpg" alt="" style="max-width:90%" style="max-width:90%" border="0"> を参照) を参照することができます。 <br>最初に $_SERVER['HTTP_REFERER'] を検査して、要求が自分のサーバーからのものであるかどうかを判断します。この方法は、ほとんどの親切なユーザーを受け入れることができますが、最も顕著なゲストを受け入れることはできず、部分内の参照者情報を変更して、表のサーバーから転送されるようにすることができます。プロセステーブル交換を処理するより良い方法は、1つの文字列または時間に基づいてレカードを生成し、このレカードを会議の量およびテーブルに入れることである。一致しない場合は、テーブルのプロセス サブ本からデータが送信されたことがわかります。 <br> ロボットのレジスタを作成するには、以下に示すように、PHP 内にある md5()、uniqid()、および rand() 関数を使用できます。防御远程表单提交<br> <br>[php]<?php<br />session_start();<br />if ($_POST['submit'] == “go”){<br />//トークンをチェック<br />if ($_POST['token'] == $_SESSION['token']){<br /> //strip_tags<br /> $name = trip_tags($_POST['name']);<br /> $name = substr($name,0,40);<br /> //潜在的な 16 進文字をすべて削除します<br /> $name = cleanHex($name);<br /> //処理を続行… .<br />}else{<br /> //すべての処理を停止します。リモートフォーム投稿試行!<br />}<br />}<br />$token = md5(uniqid(rand(), true));<br />$_SESSION['token']= $token;<br />function cleanHex($input){<br />$clean = preg_replace ("![][xX]([A-Fa-f0-9]{1,3})!", "",$input);<br />return $clean;<br />}<br />?><br><フォームアクション=”<?php echo $_SERVER['PHP_SELF'];?>” Method=”post”><br><p><label for=”name”>名前</label><br><input type=”text” name=”name” id=”name” size=”20 '' maxlength=”40″/></p><br><input type=”hidden” name=”token” value=”<?php echo $token;?>”/><br><p> ;<input type=”submit” name=”submit” value=”go”/></p><br></form><br>[/php]<br>この技术は有能です、これは次の理由によりますPHP セッション データはサーバー間で転送できません。 誰かが PHP ソース コードを取得すると、それが自分のサーバーに転送され、そのサーバーに情報が送信されます。 <br><br>セッション終了<br><br>この教程では多くの問題を解決しています:<br> mysql_real_escape_string()を使用してSQL注入の問題を防ぎます。 <br>正则表达式和を使用するstrlen() を使用して、GET データが変更されていないことを確認します。 <br> 正しい表形式と strlen() を使用して、ユーザーが送信したデータが内部ストレージ領域を溢れさせないようにします。 <br> 改ざんデータによるシステムのこのような突破口を回避します。 <br> より高いレベルの、ファイルの埋め込み、HTTP アクセス、その他の漏洩などの、ユーザーによるサーバーへのアクセスを防止する方法を使用します。発見された知識は、現在のコンテンツをより安全にするために、安全性を十分に高めるのに役立ちます。 <br>文章来源:http://bbs.phpchina.com/thread-105020-1-1.html<br></p> <p></p>http://www.bkjia.com/PHPjc/909085.html<p align="left"></p> <div style="display:none;">www.bkjia.com<span id="url" itemprop="url"></span>tru​​e<span id="indexUrl" itemprop="indexUrl"></span>http://www.bkjia.com/PHPjc/909085.html<span id="isOriginal" itemprop="isOriginal"></span>技術記事<span id="isBasedOnUrl" itemprop="isBasedOnUrl"></span> PHP アプリケーションの安全性を確保し、php アプリケーションの開始前に安全性を確保する この教義では、自分の PHP Web アプリケーションに安全性をどのように追加するかを検討します。 <span id="genre" itemprop="genre"></span> </div></div><div class="nphpQianMsg"><div class="clear"></div></div><div class="nphpQianSheng"><span>声明:</span><div>この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。</div></div></div><div class="nphpSytBox"><span>前の記事:<a class="dBlack" title="PHP の学習 -- URL の解析_PHP チュートリアル" href="https://m.php.cn/ja/faq/293157.html">PHP の学習 -- URL の解析_PHP チュートリアル</a></span><span>次の記事:<a class="dBlack" title="PHP の学習 -- URL の解析_PHP チュートリアル" href="https://m.php.cn/ja/faq/293159.html">PHP の学習 -- URL の解析_PHP チュートリアル</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>関連記事</h2><em><a href="https://m.php.cn/ja/article.html" class="bBlack"><i>続きを見る</i><b></b></a></em><div class="clear"></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-6t+ed+2i-1n-4w" data-ad-client="ca-pub-5902227090019525" data-ad-slot="8966999616"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><ul class="nphpXgwzList"><li><b></b><a href="https://m.php.cn/ja/faq/1.html" title="cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法" class="aBlack">cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ja/faq/1.html" title="cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法" class="aBlack">cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ja/faq/1.html" title="cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法" class="aBlack">cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ja/faq/1.html" title="cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法" class="aBlack">cURL を使用して PHP で Get リクエストと Post リクエストを実装する方法</a><div class="clear"></div></li><li><b></b><a href="https://m.php.cn/ja/faq/2.html" title="正規表現内のすべての式記号 (概要)" class="aBlack">正規表現内のすべての式記号 (概要)</a><div class="clear"></div></li></ul></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="5027754603"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><footer><div class="footer"><div class="footertop"><img src="/static/imghwm/logo.png" alt=""><p>福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!</p></div><div class="footermid"><a href="https://m.php.cn/ja/about/us.html">私たちについて</a><a href="https://m.php.cn/ja/about/disclaimer.html">免責事項</a><a href="https://m.php.cn/ja/update/article_0_1.html">Sitemap</a></div><div class="footerbottom"><p> © php.cn All rights reserved </p></div></div></footer><script>isLogin = 0;</script><script type="text/javascript" src="/static/layui/layui.js"></script><script type="text/javascript" src="/static/js/global.js?4.9.47"></script></div><script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script><link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css' type='text/css' media='all'/><script type='text/javascript' src='/static/js/viewer.min.js?1'></script><script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script><script>jQuery.fn.wait = function (func, times, interval) { var _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = this, _selector = this.selector, //选择器 _iIntervalID; //定时器id if( this.length ){ //如果已经获取到了,就直接执行函数 func && func.call(this); } else { _iIntervalID = setInterval(function() { if(!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = $(_selector); //再次选择 if( _self.length ) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; } $("table.syntaxhighlighter").wait(function() { $('table.syntaxhighlighter').append("<p class='cnblogs_code_footer'><span class='cnblogs_code_footer_icon'></span></p>"); }); $(document).on("click", ".cnblogs_code_footer",function(){ $(this).parents('table.syntaxhighlighter').css('display','inline-table');$(this).hide(); }); $('.nphpQianCont').viewer({navbar:true,title:false,toolbar:false,movable:false,viewed:function(){$('img').click(function(){$('.viewer-close').trigger('click');});}}); </script></body><!-- Matomo --><script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://tongji.php.cn/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '9']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script><!-- End Matomo Code --></html>