許可されたページを配列/使用スイッチなどに配置せずに$_GETを含むページを含める最も安全な方法は何でしょうか。ページがたくさんあるので、ありがとうございません。
$ content = addlashes($ _ GET ['content']); if(file_exists(PAGE_PATH。 "$ content.html")){ include(PAGE_PATH。 "$ content.html"); }
それはどれくらい安全ですか?
ありがとう。
入力に有効なパターンがあるかどうかを確認すると、より安全に眠ることができます。たとえば、含まれているファイルにサブディレクトリがなく、常に英数字であることがわかっているとします。
if (preg_match('/^[a-z0-9]+$/', $_GET['page']))
{
$file=PAGE_PATH.$_GET['page'].".html";
if (file_exists($file))
{
readfile($file);
}
}
私はreadfileを使用しましたが、.htmlファイルが静的であるかのように、includeを使用する必要はありません。
このアプローチで考えられる欠陥は、システム内の任意のHTMLファイルへのパスを設計し、それをPHPとして実行できることです。ファイルシステム上で独自に考案したHTMLファイルを取得する方法を見つけることができれば、スクリプトを介してそれを実行できます。
これは非常に悪い習慣です。ユーザーが提供する変数からコードを直接インクルードしようとするのではなく、実行または取得する必要があるコードへのディスパッチを処理するようにコントローラーをセットアップする必要があります。ファイルを含めるときは、ユーザー入力を信頼しないでください。含めたくないものを含めることを妨げるものは何もありません。
「a-zA-Z-」のみを受け入れる正規表現と照合します。
編集:特定のパターンをブロックするのは良い考えではないと思います。私が言ったように、エクスプロイトを引き起こさないことがわかっている文字のみを受け入れる正規表現を使用したいと思います。
「許可された」ページのセットがすべての下PAGE_PATH
に存在すると仮定すると、次のようなものを提案する可能性があります。
..
(パストラバーサルの試みである可能性があります)PAGE_PATH
(うまくいけば)安全なパスに明示的にプレフィックスを付けて含めるページ名がすべて英数字などの一貫した規則に従っている場合、理論的には正規表現を使用して検証し、「不正な」ページ名を拒否することができます。
これらの問題については、PHPのWebサイトでさらに議論されています。
ページを表示する前に実際にページが存在することを確認しているため、一般的に安全に見えます。ただし、有効な $_SESSION クレデンシャルを使用して閲覧できないようにするページのブラックリストを作成したい場合があります。これは、配列/スイッチを使用して行うことも、特定のディレクトリにすべての特別なページを配置して、それを確認することもできます。
最初にすべての HTML テンプレートを含むディレクトリをスキャンし、すべてのテンプレート名を配列にキャッシュして、GET パラメータを検証できるようにすることができます。ただし、この配列をキャッシュしても、何らかのオーバーヘッドが発生します。
最も安全な方法は、リクエストを少しクリーンアップすることです。
../
^\/
そこから、彼らが要求しているファイルが存在し、読み取ることができるかどうかを確認してください。あとは、それだけinclude
。
しないでください。考えられるすべての攻撃を予期することはできず、ハッキングされます。
コードを配列などから解放したい場合は、ID とパスの 2 つの列を持つデータベースを使用します。数値 ID でページをリクエストします。純粋な数値ではなく、有効な ID の範囲外の ID に対するすべての要求を無視します。SEO が気になる場合は、Stack Overflow と同様に、リンクの数値 ID の後に任意のページ名を追加できます。
データベースはヘビーデューティーである必要はありません。たとえば、SQLiteを使用できます。
XSS攻撃を防ぐには、少なくともそのようなものを使用する必要があります。
$content = htmlentities($_GET['page'], ENT_QUOTES, 'UTF-8');
また、addslashesはSQLインジェクションからユーザーを保護しません。