安全な PHP アプリケーションを作成するための 7 つの習慣の詳細な分析_PHP チュートリアル

WBOY
リリース: 2016-07-21 15:08:09
オリジナル
806 人が閲覧しました

セキュリティの問題に関しては、実際のプラットフォームとオペレーティング システムのセキュリティの問題に加えて、安全なアプリケーションを作成する必要があることに注意することが重要です。 PHP アプリケーションを作成するときは、以下の 7 つの習慣を適用して、アプリケーションに可能な限り最高のセキュリティを確保してください:
• 入力を検証する
• ファイル システムを保護する
• データベースを保護する
• セッション データを保護する
• クロスサイト スクリプトを保護する (クロスサイト スクリプティング、データの検証は、おそらく採用できる最も重要な習慣です。そして入力に関して言えば、それは非常に簡単です。ユーザーを信頼しないことです。ユーザーは優秀である可能性があり、そのほとんどがアプリケーションを期待どおりに使用している可能性があります。しかし、インプットの機会があるところでは、非常に悪いインプットが行われる可能性も高くなります。アプリケーション開発者は、アプリケーションが誤った入力を受け入れないようにする必要があります。ユーザー入力の場所と正しい値を慎重に考慮することで、堅牢で安全なアプリケーションを構築できます。
ファイル システムとデータベースの相互作用については後で説明しますが、

以下に挙げるのは、さまざまな検証に適用される一般的な検証のヒントです
:
• ホワイトリストの値を使用します
• 限られたオプションを常に再検証します
• 組み込みを使用しますエスケープ関数
• 正しいデータ型 (数値など) を確認します ホワイトリストにある値は、無効なブラックリストにある値ではなく、正しい値です。 2 つの違いは、通常、検証時に、可能な値のリストまたは範囲が無効な値のリストまたは範囲よりも小さく、その多くが不明な値または予期しない値である可能性があることです。 検証を行うときは、すべての未知の値から保護するよりも、アプリケーションで許可される値を設計して検証する方が簡単であることが多いことに注意してください。たとえば、フィールド値をすべての数値に制限するには、入力がすべて数値であることを保証するルーチンを作成する必要があります。数値以外の値を検索し、見つかった場合に無効としてマークするルーチンを作成しないでください。
ファイル システムの保護

2000 年 7 月、Web サイトが Web サーバー上のファイルに保存されている顧客データを暴露しました。 Web サイトの訪問者は、その URL を使用してデータを含むファイルを表示しました。ファイルは置き忘れられましたが、この例はファイル システムを攻撃者から保護することの重要性を強調しています。
PHP アプリケーションがファイルを操作し、ユーザーが入力できる可変データが含まれている場合は、ユーザー入力を注意深くチェックして、ユーザーがファイル システム上で不適切なアクションを実行できないことを確認してください。リスト 1 は、指定された名前のイメージをダウンロードする PHP サイトの例を示しています。
リスト 1. ファイルをダウンロードします



コードをコピーします

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

if ($_POST['submit'] == 'Download') {

$ file = $_POST[ 'fileName']; header("Content-Type: application/x-octet-stream"); header("Content-Transfer-Encoding: binary"); header("Content-Disposition:添付ファイル名 = " . $file . "";" ); $fh = fopen($file, 'r');
while (! feof($fh))
{
echo(fread($fh, 1024));
}
fclose($fh);
} else {
echo("<");
echo("title>ファイルシステムを守る");
echo("
"" Method="post">");
echo( "
echo(isset($_REQUEST['fileName']) ? $_REQUEST['fileName'] : '');
echo("" />");
echo("
");
echo("< /form>");
}


ご覧のとおり、リスト 1 のより危険なスクリプトは、セッション ディレクトリ内のファイル (「セッション データの保護」を参照) や一部のシステム ファイル (/ など) を含む、Web サーバーが読み取りアクセスを持つすべてのファイルを処理します。 /パスワード)。デモンストレーションの目的で、この例ではユーザーがファイル名を入力できるテキスト ボックスを使用しますが、ファイル名はクエリ文字列で簡単に指定できます。
ユーザー入力とファイル システム アクセスを同時に構成することは危険であるため、同時構成を避けるためにデータベースを使用し、生成されたファイル名を非表示にするようにアプリケーションを設計することが最善です。ただし、これが常に機能するとは限りません。リスト 2 は、ファイル名を検証するためのサンプル ルーチンを示しています。正規表現を使用してファイル名に有効な文字のみが使用されていることを確認し、特にドット文字をチェックします。
リスト 2. 有効なファイル名文字を確認する
コードをコピーする コードは次のとおりです:

function isValidFileName($file) {
/* .. を許可せず、任意の "単語を許可する" "character / */
return preg_match('/^(((?:.)(?!.))|w)+$/', $file);
}

データベースを保護する
2008 年 4 月米国 ある州の矯正局がクエリ文字列に SQL 列名を使用したため、機密データが漏洩しました。この侵害により、悪意のあるユーザーが表示する列を選択し、ページを送信し、データを取得することが可能になりました。このリークは、アプリケーション開発者が予期しなかった方法でユーザーがどのように入力を実行できるかを示し、SQL インジェクション攻撃から防御する必要性を示しています。
リスト 3 は、SQL ステートメントを実行するサンプル スクリプトを示しています。この場合、SQL ステートメントは同じ攻撃を許可する動的ステートメントです。このフォームの所有者は、列名を選択リストに制限しているため、フォームが安全であると考えている可能性があります。ただし、このコードには、フォームの不正行為に関する最後のヒントが 1 つ抜けています。コードがオプションをドロップダウン ボックスに制限しているからといって、他のユーザーが必要なコンテンツ (アスタリスク [*] を含む) を含むフォームを投稿できないというわけではありません。 。
リスト 3. SQL ステートメントを実行します
コードをコピーします コードは次のとおりです:



SQL インジェクションの例
< /head>

Method="post">
Value=" $_POST['account_number'] : ''); ?> " /> ;


< /form>
if ($_POST['submit'] == 'Save') {
/* フォーム処理を実行します */
$link = mysql_connect('hostname', 'user', 'password ') または
die ('接続できませんでした' . mysql_error());
$col = $_POST['col'];
$col . " FROM account_data WHERE account_number = " . $_POST['account_number'] ;
' $result = mysql_query ) または die('

' . mysql_error() . '

');
echo '';
while ($row = mysql_fetch_assoc($result)) {
echo '< ;tr> ;';
echo '
}
?




したがって、データベースを保護する習慣を身に付けるには、可能な限り動的 SQL コードの使用を避けてください。動的 SQL コードを回避できない場合は、列に対して直接入力を使用しないでください。リスト 4 は、静的列の使用に加えて、口座番号フィールドに単純な検証ルーチンを追加して、入力値が数値以外の値ではないことを確認できることを示しています。
リスト 4. 検証と mysql_real_escape_string() による保護
コードをコピーします コードは次のとおりです:



SQL インジェクションの例& lt;/ title> <br> </head><br><body><br><form id="myFrom" action="<?php echo $_SERVER['PHP_SELF']; ?>"<br> Method="post"> <br>< div><input type="text" name="アカウント番号"<BR> value="<?php echo(isset($_POST['アカウント番号']) ? <BR> $_POST['アカウント番号'] : '' ); >" /> <input type="submit"<BR> value="Save" name="submit" /></div><br><?php<br>function isValidAccountNumber ($number ) <br>{<br> Return is_numeric($number);<br>}<br>if ($_POST['submit'] == 'Save') {<br> /* 習慣 1 を覚えておいてください -- データを検証してください */<br> if! (ISSET($ _POST ['Account_Number'])&& ); "from account_data where account_number = %s; ",<br> mysql_real_escape_string($_POST['account_number']));<br> echo '</p>';<br> $result = mysql_query($select) または die('< p>' . mysql_error() . '</p>');<br> ; echo '<td>' '</ td>;<br> echo '<td>' '</body><br><br><br>この例では、mysql_real_escape_string() 関数の使用法も示しています。この関数は入力を正しくフィルタリングして、無効な文字が含まれないようにします。 magic_quotes_gpc に依存している場合は、これは非推奨であり、PHP V6 では削除される予定であることに注意する必要があります。今後は、この場合は使用を避け、安全な PHP アプリケーションを作成する必要があります。また、ISP を使用している場合は、ISP で magic_quotes_gpc が有効になっていない可能性があります。 <br>最後に、改良された例では、SQL ステートメントと出力に動的列オプションが含まれていないことがわかります。この方法を使用すると、後で別の情報を含むテーブルに列が追加された場合に、列をエクスポートできます。データベースを操作するためにフレームワークを使用している場合、そのフレームワークがすでに SQL 検証を実行している可能性があります。ドキュメントを参照してフレームワークが安全であることを確認してください。まだ不明な場合は、確認してください。データベース対話用のフレームワークを使用する場合でも、追加の検証を実行する必要があります。 <br><br><strong>セッションの保護<br></strong> デフォルトでは、PHP のセッション情報は一時ディレクトリに書き込まれます。セッション内でユーザー ID とアカウント番号を保存する方法を示すリスト 5 のフォームを考えてみましょう。 <br><strong>リスト 5. セッションにデータを保存する <br></strong><div class="codetitle"> <span style="CURSOR: pointer" onclick="doCopy('code40366')"><u> コードをコピー </u></span> コードは次のとおりです。 </div><title>セッション情報の保存


if ($_POST['submit'] == 'Save') {
$_SESSION[' userName' ] = $_POST['userName'];
$_SESSION['accountNumber'] = $_POST['accountNumber'];
}
?>
Method="post">

Value="


Value=" $_POST['アカウント番号'] : ''); " />









リスト 6 は、/tmp ディレクトリの内容を示しています。

リスト 6. /tmp ディレクトリ内のセッション ファイル


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

-rw------- 1 _www Wheel 97 Aug 18 20:00 sess_9e4233f2cd7cae35866cd 8b61d9 fa42bご覧のとおり、出力 (リスト 7 を参照) では、セッション ファイルには非常に読みやすい形式で情報が含まれています。ファイルは Web サーバー ユーザーによって読み取りおよび書き込み可能である必要があるため、セッション ファイルは共有サーバー上のすべてのユーザーに重大な問題を引き起こす可能性があります。あなた以外の誰かがこれらのファイルを読み取るスクリプトを作成し、セッションから値を取得しようとする可能性があります。 リスト 7. セッション ファイルの内容


コードをコピー

コードは次のとおりです:
userName|s:5:"ngood";accountNumber|s:9:"123456789";

パスワードの保存
データベース、セッション、ファイル システム、その他の形式を問わず、パスワードはプレーン テキストとして保存しないでください。パスワードを処理する最善の方法は、パスワードを暗号化して保存し、暗号化されたパスワードを相互に比較することです。それでも、実際には依然としてパスワードを平文で保存している人がいます。パスワードをリセットする代わりに送信できる Web サイトを使用する場合は、パスワードが平文で保存されるか、復号化用のコード (暗号化されている場合) を取得できることを意味します。後者の場合でも、復号コードを見つけて使用することができます。
セッションデータを保護するために実行できるアクションは 2 つあります。 1 つ目は、セッションに入力したものをすべて暗号化することです。ただし、データを暗号化しても完全に安全であるとは限らないため、セッションを保護する唯一の方法としてこのアプローチを慎重に使用してください。別の方法は、セッション データをデータベースなどの別の場所に保存することです。データベースを確実にロックする必要がありますが、このアプローチにより 2 つの問題が解決されます。1 つは、共有ファイル システムよりも安全な場所にデータが配置されることです。2 つ目は、アプリケーションをより簡単に拡張できるようになります。複数の Web サーバーを使用すると、同時共有セッションが複数のホストにまたがることができます。

独自のセッション永続性を実装するには、PHP の session_set_save_handler() 関数を参照してください。これを使用すると、セッション情報をデータベースに保存したり、すべてのデータを暗号化および復号化するためのハンドラーを実装したりできます。リスト 8 は、実装された関数の使用法と関数のスケルトンの例を示しています。 「リソース」セクションでデータベースの使用方法を確認することもできます。
リスト 8. session_set_save_handler() 関数の例
コードをコピーします コードは次のとおりです:

function open($save_path, $session_name)
{
/* カスタム コード */
return ( true);
}
function close()
{
/* カスタム コード */
return (true);
}
function read($id)
{
/* カスタム コード */
return (true);
}
関数書き込み ($id, $sess_data)
{
gc($maxlifetime)
{
/* カスタム コード */
return (true);
}
session_set_save_handler("open "、"閉じる"、"読む" 、"write"、"destroy"、"gc");



XSS 脆弱性からの保護

XSS 脆弱性は、2007 年にアーカイブされたすべての Web サイトの脆弱性の大部分を占めていました (「参考文献」を参照)。 XSS 脆弱性は、ユーザーが Web ページに HTML コードを挿入できる場合に発生します。 HTML コードではスクリプト タグ内に JavaScript コードを含めることができるため、ページがフェッチされるたびに JavaScript を実行できます。リスト 9 のフォームは、フォーラム、Wiki、ソーシャル ネットワーク、またはテキストを入力できるその他のサイトを表すことができます。

リスト 9. テキストを入力するフォーム


コードをコピーします

コードは次のとおりです:
XSS を入力するチャンス</title> ;<U>< /head><body></span><form id="myFrom" action="showResults.php" method="post"></div><div><textarea name="myText" rows= "4"cols="30"></textarea><br /><div class="codebody" id="code36093"><input type="submit" value="削除" name="submit" /></div><br>< ;/form> <br></body><br></html><br><br><br><br> リスト 10 は、XSS 攻撃を許可するフォームがどのように結果を出力できるかを示しています。 <br><br>リスト 10. showResults.php<br><br><br> </div> コードをコピーします<br><strong> コードは次のとおりです:<br></strong><br><html><div class="codetitle"><head><span style="CURSOR: pointer" onclick="doCopy('code35430')"><title>XSS を示す結果< /head&g t; echo("

次のように入力しました:

");
echo("

");
echo($_POST ['myText'] );
echo("

");
?>




リスト 11 は、新しいウィンドウが表示される基本的な例を示しています。ポップアップしてGoogleのホームページを開きます。 Web アプリケーションが XSS 攻撃から保護されていない場合、重大な損害が発生する可能性があります。たとえば、誰かがフィッシング目的でサイトのスタイルを模倣したリンクを追加する可能性があります (「参考文献」を参照)。

リスト11. 悪意のある入力テキストのサンプル



コードをコピー

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



XSS 攻撃を防ぐには、変数の値が出力に出力される限り、入力をフィルタリングする必要があります。 htmlentities() 関数。習慣 #1: Web アプリケーションへの名前、電子メール アドレス、電話番号、請求先情報の入力において、入力データをホワイトリストの値で検証することを忘れないでください。
テキスト入力を示すより安全なページを以下に示します。
リスト 12. より安全なフォーム
コードをコピーします コードは次のとおりです:



XSS を示す結果
< ;/head > ;

echo("

次のように入力しました:

");
echo("

");
echo(htmlentities ($_POST[ 'myText']));
echo("

");
?>



無効な投稿から保護する
フォームスプーフィングとは、誰かが不適切な場所からフォームに投稿することを指します。フォームを偽装する最も簡単な方法は、フォームへの送信を通じてすべての値を渡す Web ページを作成することです。 Web アプリケーションはステートレスであるため、公開されるデータが指定された場所からのものであることを確認する確実な方法はありません。 IP アドレスからホスト名まですべてがスプーフィングされる可能性があります。リスト 13 は、情報を入力できる典型的なフォームを示しています。
リスト 13. テキストを処理するフォーム
コードをコピー コードは次のとおりです:



フォームスプーフィングの例
< ;/head > ;

if ($_POST['submit'] == 'Save') {
echo("

あなたのテキストを処理しています: ");
echo($_POST ['myText']);
echo("

");
}
?>



リスト 14 は、何が起こるかを示しています。リスト 13 に公開 フォーム内のフォームを表します。これを試すには、フォームを Web サイトに配置し、リスト 14 のコードを HTML ドキュメントとしてデスクトップに保存します。フォームを保存したら、ブラウザで開きます。その後、データを入力してフォームを送信すると、データがどのように処理されるかを確認できます。
リスト 14. データを収集するためのフォーム
コードをコピーします コードは次のとおりです:



データの収集







フォーム スプーフィングの潜在的な影響は、ドロップダウン ボックス、ラジオ ボタン、チェックボックス、またはその他の入力制限のあるフォームがある場合、フォームが偽装されている場合、これらの制限は何の意味も持ちません。リスト 15 のコードを考えてみましょう。このコードには、無効なデータを含むフォームが含まれています。
リスト 15. 無効なデータを含むフォーム
コードをコピー コードは次のとおりです:



データの収集
< ; /head>

Method="post"> value="これが、はい/いいえの回答に対する有効な応答であるはずがありません..." />

< ;/form>



考えてみてください: ユーザー入力の量を制限するドロップダウン ボックスまたはラジオ ボタンがある場合、入力の検証について心配する必要はないと考えるかもしれません。結局のところ、入力フォームはユーザーが特定のデータのみを入力できるようにするものですよね?フォームのなりすましを制限するには、発行者の ID が本物であることを確認する検証が必要です。使い捨てタグを使用することもできます。この手法を使用してもフォームが完全に安全になるわけではありませんが、フォームのなりすましはより困難になります。マークアップはフォームが呼び出されるたびに変更されるため、攻撃者となる場合は、送信されたフォームのインスタンスを取得し、マークアップを削除して、それを偽のフォームに組み込む必要があります。このテクノロジーを使用すると、悪意のあるユーザーが永続的な Web フォームを構築してアプリケーションに不適切なリクエストを発行することを防ぐことができます。リスト 16 はフォーム マークアップの例を示しています。
リスト 16. 使い捨てフォームタグの使用
コードをコピー コードは次のとおりです。

session_start();
?>


SQL インジェクション テスト


echo 'セッション トークン=' $_SESSION['token'];
echo '
echo 'form=' からのトークン . $_POST['token'];
echo '
';
if ($_SESSION['token'] == $_POST['token '] ) {
/* いいですね、大丈夫です...もう 1 つ作成します */
} else {
echo '

去ってください!

';
}
$token = md5(uniqid (rand(), true));
$_SESSION['token'] = $token;
?>
Method="post">

< ;input type="text" name="myText"
value="" >





CSRF によって保護されている場合
クロスサイト リクエスト フォージェリ (CSRF 攻撃) は、ユーザー権限を使用して実行される攻撃の結果です。 CSRF 攻撃では、ユーザーが意図しない共犯者になってしまう可能性があります。リスト 17 は、特定のアクションを実行するページの例を示しています。このページは Cookie からユーザーのログイン情報を検索します。 Cookie が有効である限り、Web ページはリクエストを処理します。

リスト 17. CSRF の例
コードをコピーします コードは次のとおりです:

CSRF 攻撃は通常、 タグの形式で行われます。これは、ブラウザーが画像を取得するために無意識のうちにこの URL を呼び出すためです。ただし、画像ソースは、受信パラメータに基づいて処理される同じサイト内のページ URL にすることもできます。この タグが XSS 攻撃 (文書化された攻撃の中で最も一般的) と組み合わされると、ユーザーは知らないうちに資格情報に対していくつかのアクションを簡単に実行できるため、偽造されてしまいます。
CSRF 攻撃から保護するには、フォームの投稿を検証するときに使用されるワンタイム タグ方式を使用する必要があります。また、$_REQUEST の代わりに明示的な $_POST 変数を使用します。リスト 18 は、ページが GET リクエスト経由で呼び出されるか、ページにフォームを送信することによって呼び出されるかに関係なく、同じ Web ページを処理する悪い例を示しています。

リスト 18. $_REQUEST からデータを取得します
コードをコピーします コードは次のとおりです:


両方の投稿を処理し、</title> を取得します;<br> </head><br><body><br><?php<br>if ($_REQUEST['submit'] == 'Save') {<br> echo("<p>テキストを処理しています: ") ;<br> echo(htmlentities($_REQUEST['text']));<br> echo("</p>");<br>}<br>?><br></body><br></html><br><br> </div>List 19 表示 フォーム POST のみを使用してクリーンなページを作成しました。 <br><br>リスト 19. $_POST からのみデータを取得します<strong><br></strong><div class="codetitle"> <span style="CURSOR: pointer" onclick="doCopy('code2318')">コードをコピーします<u></u> コードは次のとおりです:</span><div class="codebody" id="code2318"> <br><html><br><head><br><title>両方の投稿を処理し、


if ($_POST['submit' ] == '保存') {
echo("

あなたのテキストを処理しています: ");
echo(htmlentities($_POST['text']));
echo("

" );
}
?>
悪意のある攻撃の被害者。他の多くの習慣と同様、これらも最初は慣れるのが難しいかもしれませんが、時間の経過とともに習慣に従うようになります。
最初の習慣が鍵であることを覚えておいてください: 入力を検証することです。入力に無効な値が含まれていないことを確認した後、ファイル システム、データベース、セッションの保護を継続できます。最後に、PHP コードが XSS 攻撃、フォーム スプーフィング、CSRF 攻撃に耐性があることを確認してください。これらの習慣を身につければ、単純な攻撃から身を守ることができます。

http://www.bkjia.com/PHPjc/327487.html
www.bkjia.com
tru​​e
http://www.bkjia.com/PHPjc/327487.html

技術記事セキュリティの問題に関しては、実際のプラットフォームとオペレーティング システムのセキュリティの問題に加えて、安全なアプリケーションを作成する必要があることに注意することが重要です。 PHP アプリケーションを作成するときは...

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
' ;
echo '