ホームページ  >  記事  >  バックエンド開発  >  PHPプログラムの脆弱性の原因分析と予防方法の解説_PHPチュートリアル

PHPプログラムの脆弱性の原因分析と予防方法の解説_PHPチュートリアル

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

インクルードの乱用

1. 脆弱性の理由:

Include は、PHP Web サイトを作成する際に最も一般的に使用される関数であり、相対パスをサポートします。入力変数を Include パラメータとして直接使用する PHP スクリプトが多数あり、任意のスクリプト参照や絶対パスの漏洩などの脆弱性が発生します。次のコードを見てください:

...
$includepage=$_GET["includepage"]
...
;

明らかに、必要なページを取得するには、さまざまな Includepage 変数を送信するだけです。存在しないページを送信すると、PHP スクリプトでエラーが発生し、実際の絶対パスが漏洩する可能性があります (この問題の解決策は次の記事で説明されています)。

2. 脆弱性の解決:

この脆弱性に対する解決策は非常に簡単で、最初にページが存在するかどうかを確認し、それを含めることです。より厳密には、配列を使用して、含めることができるファイルを指定します。次のコードを見てください:


コードをコピーします コードは次のとおりです:
$pagelist=array("test1.php","test2.php","test3.php"); //これは、 include がインクルードできることを規定しています File
if(isset($_GET["includepage"])) // $includepage があるかどうかを判断します
{
$includepage=$_GET["includepage"]
foreach($pagelist as $prepage)
{
if( $includepage==$prepage) // ファイルが許可リストにあるかどうかを確認します
{
$checkfind=true
}
}
if; ($checkfind==true){ unset( $checkfind); }
else("無効な参照ページ!") }
}


これで問題はうまく解決できます。
ヒント: この問題が発生する関数には、require()、require_once()、include_once()、readfile() などが含まれます。記述する際には注意してください。

入力変数はフィルタリングされません

1. 脆弱性の理由:

この脆弱性は長い間 ASP に出現しており、当時は無数のインジェクション脆弱性を引き起こしていました。しかし、当時は PHP の影響力が小さかったため、これに注目する人は多くありませんでした。 PHP の場合、より多くの PHP スクリプトがテキスト データベースを使用するため、この脆弱性の影響は ASP の影響よりも大きくなります。もちろん、SQL ステートメント インジェクションの問題もあります。より古典的な例を挙げると、最初はデータベースです:


コードをコピーします

コードは次のとおりです:$id=$_GET["id"];
$query="SELECT * FROM my_table where id='".$id."'" //非常に古典的な SQL インジェクションの脆弱性
$result=mysql_query($query);

を使用できることは明らかです。ここに注入します。データベースの他の内容を取得しましょう。ここでは詳しく説明しませんが、ASP インジェクションと同様に、以前のブラック ディフェンスを参照してください。次に、テキスト データベースの問題を見てみましょう:


コードをコピーします
コードは次のとおりです: $text1=$_POST["text1"] $text2=$_POST["text2"]; ;
$text3=$ _POST["text3"];
$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");

Text の脆弱性は以下の可能性があります。もっと深刻だと言いました。送信された変数に小さな PHP コードを挿入すると、このテキスト データベース test.php を PHP バックドアに変えることができます。アップロード コードを挿入するだけでも、完全な PHP バックドアをアップロードできます。次に、権限を増やすと、サーバーがあなたのものになります。



2. 脆弱性の解決:


この脆弱性に対する解決策は実際には非常に簡単で、送信されたすべての変数を厳密にフィルターすることです。一部の機密性の高い文字を置き換えます。 PHP が提供する htmlspecialchars() 関数を使用して、HTML のコンテンツを置き換えることができます。以下に例を示します:

コードをコピーします

コードは次のとおりです:


//フィルター関数を構築します
function flt_tags($text)
{
$badwords=array("fuck","fuck") //ワードフィルターリスト
$text=rtrim($text); badwords as $badword) //単語のフィルタリングはここで行われます
{
if(stristr($text,$badword)==true){ die("エラー: 送信したコンテンツには機密性の高い単語が含まれています。機密性の高いコンテンツは送信しないでください。 " ); }
}
$text=htmlspecialchars($text); //HTML 置換
//これら 2 行のキャリッジリターンを
に置換します $text=str_replace("r"," ",$text);

$text=str_replace("n","",$text);
$text=str_replace("&line;","│",$ text); //テキストデータベースの区切り文字「&line;」を全角の「│」に置き換えます
$text=preg_replace("/s{ 2 }/"," ",$text); Network Management Alliance
$text=preg_replace("/t/"," ",$text); // 引き続きスペースを置換します
if(get_magic_quotes_gpc()){ $text=stripslashes($text) } // magic_quotes がオンになったら続行します'
return $text
} の置き換え。
$text1=$_POST["text1"];

$text2=$_POST["text2"];

//すべての入力をフィルターします
$text1=flt_tags($text1);
$text3=flt_tags($text3);

$fd=fopen("test.php","a");

fwrite($fd,"rn$text1&line;$text2&line;$text3");


一部置換後フィルタリングを使用すると、データをテキストまたはデータベースに安全に書き込むことができます。



管理者の判断が不完全です


1. 脆弱性の理由: スクリプトの作成には PHP を使用しますが、これには通常、管理者の権限の問題が伴います。一部のスクリプトは、管理者権限に対して「はい」の判定のみを行い、「いいえ」の判定を無視することがよくあります。 PHP 設定ファイルで register_globals がオンになっている場合 (4.2.0 以降のバージョンではデフォルトでオフになっていますが、便宜上オンにしている人も多く、これは非常に危険な動作です)、変数が偽装のために送信される状況が発生します。管理者。コード例を見てみましょう:

コードをコピーします

コードは次のとおりです:


$cookiesign="admincookiesign" //管理者の Cookie 変数かどうかを確認します$adminsign=$_COOKIE["sign "]; // ユーザーの Cookie 変数を取得します if($adminsign==$cookiesign) {
$admin=true;

if($admin){ echo "管理者ステータスになりました。";

とても安全そうです、笑。ここで、PHP 構成ファイルで register_globals がオンになっていると仮定します。 「test.php? admin=true」というアドレスを送信しましたが、結果を見ましたか?正しい Cookie はありませんが、register_globals がオンになっているため、送信した管理変数は自動的に true として登録されます。さらに、スクリプトには「いいえ」の判定がないため、admin=true によって管理者権限を正常に取得できます。この問題はほとんどの Web サイトやフォーラムに存在します。


2. 脆弱性の解決:


この問題を解決するには、スクリプトに管理者に対する「いいえ」の判断を追加するだけです。ここでは、PHP 構成ファイルで register_globals がオンになっていると仮定します。コードを見てください:


コードをコピーします コードは次のとおりです:


$cookiesign="admincookiesign" //管理者の Cookie 変数かどうかを判断します

$adminsign=$_COOKIE["sign"] ; // ユーザー Cookie 変数を取得します if($adminsign==$cookiesign) { $admin=true;
}
else
{
$admin=false; }

if($admin){ echo "これで管理者のステータスになります。" }

このように、攻撃者が正しい Cookie なしで変数 admin=true を送信したとしても、スクリプトは今後の判断で $admin を False に設定します。これで問題の一部が解決されます。ただし、$admin は変数であるため、将来的に他のスクリプト参照に抜け穴が発生し、$admin が再割り当てされると、新たな危機が発生します。したがって、管理者権限の決定を保存するには定数を使用する必要があります。 Define() ステートメントを使用して、管理者権限を記録するための管理定数を定義します。この後に再割り当てすると、エラーが発生し、保護の目的が達成されます。次のコードを見てください:



コードをコピーします

コードは次のとおりです:


$cookiesign="admincookiesign" //管理者の Cookie 変数かどうかを判断します
$adminsign=$_COOKIE["sign"]; // ユーザーの Cookie 変数を取得します Cookie 変数
if($adminsign==$cookiesign) { define(admin,true); }
else
{
define(admin,false)
} if(admin){ echo "これで管理者のステータスになります。" ; }



Define ステートメントを使用するので、Admin 定数を呼び出すときは、その前に変数記号 $ を習慣的に追加せず、Admin と !admin を使用することに注意してください。

テキストデータベースが公開されました

1. 脆弱性の理由:

前述したように、テキスト データベースは柔軟性が高いため、外部サポートは必要ありません。さらに、PHP には非常に強力なファイル処理機能があるため、PHP スクリプトではテキスト データベースが広く使用されています。テキスト データベースを使用する優れたフォーラム プログラムもいくつかあります。ただし、得もあれば損もあり、テキスト データベースのセキュリティは他のデータベースに比べて低くなります。

2. 脆弱性の解決:

テキストデータベースは通常のファイルとして、MDBと同様にダウンロードできます。したがって、MDB と同じ方法でテキスト データベースを保護する必要があります。テキスト データベースのサフィックス名を .PHP に変更します。そしてデータベースの最初の行に結合します。このようにして、テキスト データベースは PHP ファイルとして扱われ、実行は最初の行で終了します。つまり、テキスト データベースを保護する目的を達成するために、空のページが返されます。

間違ったパスが漏洩しました

1. 脆弱性の理由:

PHP でエラーが発生すると、エラー スクリプトの場所、行番号、および理由が表示されます。例:

注意: 未定義の定数テストの使用 - D:interpubbigflytest.php の 3 行目で「test」とみなします

それは大したことではないと言う人が多いです。しかし、実際のパスが漏洩した場合の影響は、一部の侵入者にとっては想像を絶するものであり、実際、多くのサーバーがこの問題を抱えています。

一部のネットワーク管理者は、問題を解決するために、PHP 設定ファイルの display_errors を Off に設定するだけですが、この方法はあまりにも消極的すぎると思います。場合によっては、デバッグのために PHP がエラー情報を返す必要があることがあります。また、何か問題が発生した場合は、ユーザーに説明したり、別のページに移動したりする必要がある場合もあります。

2. 脆弱性の解決:

PHP は 4.1.0 以降、エラー処理ハンドルをカスタマイズするための関数 set_error_handler() を提供していますが、これについて知っているスクリプト作成者はほとんどいません。多くの PHP フォーラムの中で、この状況に対処しているのを見たことがありません。 set_error_handler の使用法は次のとおりです:

string set_error_handler (コールバック error_handler [, int error_types])

今度は、カスタム エラー処理を使用して実際のパスを除外します。

コードをコピーします コードは次のとおりです:

//admin は管理者の ID 決定、true は管理者です。
//カスタム エラー処理関数には、これら 4 つの入力変数 $errno、$errstr、$errfile、$errline が必要です。そうでない場合は無効になります。
function my_error_handler($errno,$errstr,$errfile,$errline)
{
//管理者でない場合は実際のパスをフィルタリングします
if(!admin)
{
$errfile=str_replace(getcwd()," ", $errfile);
$errstr=str_replace(getcwd(),"",$errstr);
}

switch($errno)
{
case E_ERROR:
echo "エラー: [ID $errno] $errstr (行: $errfile の $errline)
n"; プログラムの実行が停止しました。管理者に連絡してください。 . ";
//エラー レベルのエラーが発生した場合はスクリプトを終了します
exit;
break;
case E_WARNING:
echo "WARNING: [ID $errno] $errstr (Line: $errline of $errfile)
n";
break ;
デフォルト:
//通知レベルのエラーを表示しません
}
}

//エラー処理を my_error_handler 関数に設定する

set_error_handler("my_error_handler");




このようにして、セキュリティとデバッグの利便性の間の矛盾をうまく解決できます。また、Web サイトのスタイルに合わせてエラー メッセージをより美しくすることも考えられます。ただし、次の 2 つの点に注意してください:


(1) E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING はこのハンドルでは処理されません。つまり、最もオリジナルの方法で表示されます。ただし、これらのエラーはコンパイル エラーまたは PHP カーネル エラーによって発生するものであり、通常の状況では発生しません。

(2) set_error_handler()使用後はerror_reporting()が無効になります。つまり、すべてのエラー (上記のエラーを除く) は、処理のためにカスタム関数に渡されます。

set_error_handler() に関するその他の情報については、公式 PHP マニュアルを参照してください。


POST の脆弱性

1. 脆弱性の理由:

前に述べたように、変数を登録するために register_globals に依存するのは悪い習慣です。一部のゲストブックやフォーラム プログラムでは、ページの取得方法や投稿の間隔をさらに厳密にチェックする必要があります。スパム投稿や外部からの投稿を防ぐため。以下のゲストブック プログラムのコードを見てみましょう:


コードをコピーします コードは次のとおりです:

...
$text1=flt_tags($text1);
$text3=flt_tags($text3);
$fd=fopen("data.php","a"); fwrite($fd,"rn$text1&line;$text2&line;$text3");



明らかに、 URL「post.php?text1=testhaha&text2=testhaha&text3= testhaha」を送信します。データは通常どおりファイルに書き込まれます。このプログラムは、変数のソースやブラウザがページを取得した方法を検出しません。このページに複数の投稿を送信すると、フラッドが発生します。この脆弱性を利用してフォーラムやゲストブックに広告を掲載するソフトウェアも存在しており、これは恥ずべき行為です(友人のゲストブックは1週間で10ページ以上の書き込みがあり、どうしようもありませんでした)。


2. 脆弱性の解決:

データを処理して保存する前に、まずブラウザーがページを取得する方法を決定します。 $_SERVER["REQUEST_METHOD"] 変数を使用して、ブラウザのページ取得方法を取得します。 「POST」になっているか確認してください。スクリプトでセッションを使用して、ユーザーが通常のチャネル (つまり、送信コンテンツが入力されるページ) を通じてデータを送信したかどうかを記録します。または、$_SERVER["HTTP_REFERER"] を使用してこれを検出しますが、これはお勧めできません。一部のブラウザは REFERER を設定しないため、一部のファイアウォールも REFERER をブロックします。さらに、送信されたコンテンツをチェックして、データベース内に重複したコンテンツがないかどうかを確認する必要もあります。ゲストブックを例として、Session を使用して決定します。 閲覧コンテンツを入力するページで、フロントエンドに以下を追加します。

$_SESSION["allowgbookpost"]=time() //登録が完了した時刻
;

メッセージデータを受け付けて保存するページでは、データ処理の前にセッションを使用して次の処理も実行します:


コードをコピー

コードは次のとおりです: if(strtoupper($_SERVER[ "REQUEST_METHOD"]) !=”POST”){ die("エラー: 外部から送信しないでください。") } //ページ取得方法がPOSTかどうかを確認します
if(!isset($_SESSION["allowgbookpost"]) or (time() -$_SESSION["allowgbookpost"] < 10)){ die("エラー: 外部から送信しないでください。") } //メッセージが入力された時刻を確認します
if(isset($) _SESSION["gbookposttime"]) and (time()-$_SESSION["gbookposttime"] < 120)){ die("エラー: 2 回のメッセージ送信の間隔は 2 分以上でなければなりません。"); //メッセージ間隔を確認する

unset($_SESSION["allowgbookpost"]) //一度に複数の送信が入力ページに入らないように、allowgbookpost 変数の登録を解除します
$_SESSION["gbookposttime"]=time();スパムや悪意のある攻撃を防ぐためにメッセージを送信する...



データの処理と保存


http://www.bkjia.com/PHPjc/736794.html

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/736794.html技術記事 include の悪用 1. 脆弱性の理由: Include は、PHP Web サイトを作成する際に最も一般的に使用される関数であり、相対パスをサポートします。入力変数を Include パラメータとして直接使用する PHP スクリプトが多数あり、何らかの問題が発生します...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。