セキュリティは興味深い概念であり、多くの人々を魅了しています。残念ながら、それは複雑な主題であり、専門家でさえそれを間違えます。 Google(CSRF)、Facebook(より多くのCSRF)、いくつかの主要なオンライン小売業者(主にSQLインジェクション/ XSS)、および企業と個人の両方の何千もの小さなサイトにセキュリティホールを見つけました。
これらは私の推奨事項です:
1)パラメータ化されたクエリを使用する
パラメータ化されたクエリは、クエリに渡された値を個別のデータとして処理するように強制するため、入力値をDBMSでSQLコードとして解析することはできません。多くの人は、mysql_real_escape_string()
を使用して文字列をエスケープすることをお勧めします 、しかし一般的な信念に反して、それはそうではありません SQLインジェクションのキャッチオールソリューション。このクエリを例に取ってください:
SELECT * FROM users WHERE userID = $_GET['userid']
$_GET['userid']
の場合 1 OR 1=1
に設定されています 、特殊文字はなく、フィルタリングされません。これにより、すべての行が返されます。または、さらに悪いことに、1 OR is_admin = 1
に設定されている場合はどうなりますか。 ?
パラメータ化されたクエリは、この種のインジェクションの発生を防ぎます。
2)入力を検証します
パラメータ化されたクエリは素晴らしいですが、予期しない値がコードに問題を引き起こす場合があります。それらが範囲内にあり、現在のユーザーができないはずの変更を許可しないことを検証していることを確認してください。
たとえば、パスワードを変更するスクリプトにPOST要求を送信するパスワード変更フォームがあるとします。ユーザーIDをフォームの非表示変数として配置すると、変更される可能性があります。 id=123
を送信する id=321
の代わりに 他人のパスワードを変更することを意味する場合があります。タイプ、範囲、アクセスに関して、すべてが正しく検証されていることを確認してください。
3)htmlspecialcharsを使用して、表示されたユーザー入力をエスケープします
ユーザーが「自己紹介」を次のように入力するとします:
</div><script>document.alert('hello!');</script><div>
これに関する問題は、ユーザーが入力したマークアップが出力に含まれることです。これをブラックリストで自分でフィルタリングしようとするのは悪い考えです。 htmlspecialchars
を使用する 文字列を除外して、HTMLタグがHTMLエンティティに変換されるようにします。
4)$_REQUESTを使用しないでください
クロスサイトリクエストフォージェリ(CSRF)攻撃は、ユーザーにリンクをクリックするか、ログインしているサイトでアクションを実行するスクリプトを表すURLにアクセスさせることで機能します。$_REQUEST
変数は$_GET
の組み合わせです 、$_POST
および$_COOKIE
、つまり、POSTリクエストで送信された変数(つまり、input
を介して送信された変数の違いを区別できないことを意味します) フォーム内のタグ)またはGETの一部としてURLに設定された変数(例:page.php?id=1
。
ユーザーが誰かにプライベートメッセージを送信したいとします。彼らはPOSTリクエストをsendmessage.php
に送信するかもしれません 、to
、subject
およびmessage
パラメータとして。次に、誰かが代わりにGETリクエストを送信するとします。
sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!
$_POST
を使用している場合 、$_GET
で設定されているため、これらのパラメータは表示されません。 代わりは。コードには$_POST['to']
は表示されません または他の変数のいずれかであるため、メッセージは送信されません。ただし、$_REQUEST
を使用している場合 、$_GET
および$_POST
一緒にスタックするため、攻撃者はこれらのパラメータをURLの一部として設定できます。ユーザーがそのURLにアクセスすると、誤ってメッセージを送信します。本当に心配なのは、ユーザーが何もする必要がないことです。攻撃者が悪意のあるページを作成した場合、そのページにはiframe
が含まれている可能性があります それはURLを指します。例:
<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!">
</iframe>
その結果、ユーザーは何もしなかったことに気付かずにメッセージを送信します。このため、$_REQUEST
は避けてください。 $_POST
を使用します および$_GET
代わりに。
5)与えられたすべてのものを疑わしい(または悪意のある)ものとして扱います
ユーザーが何を送っているのかわかりません。それは合法かもしれません。攻撃の可能性があります。ユーザーから送信されたものは絶対に信用しないでください。正しいタイプに変換し、入力を検証し、ホワイトリストを使用して必要に応じてフィルタリングします(ブラックリストは避けてください)。これには、$_GET
を介して送信されたものが含まれます 、$_POST
、$_COOKIE
および$_FILES
。
これらのガイドラインに従えば、セキュリティの面で合理的な立場になります。