Webページは、次のように、フィルタリングせずにパラメーターredirect
で指定されたURLにリダイレクトします。
$newURL=$_GET["redirect"];
header('Location: '.$newURL);
login.php?redirect=home.php
それが入力をエコーする場合、XSS攻撃を実行することが可能であることがわかっていますが、それがヘッダーメソッドで使用されているときにコードを挿入できますか?これは安全なスクリプトですか?
いいえ、これは安全ではなく、実行すべきではありません。実際、これは OWASP Top 1 の最後の1つです。
A10。未検証のリダイレクトと転送
Webアプリケーションは頻繁にユーザーを他のページやWebサイトにリダイレクトして転送し、信頼できないデータを使用して宛先ページを決定します。適切な検証がなければ、攻撃者は被害者をフィッシングサイトやマルウェアサイトにリダイレクトしたり、転送を使用して不正なページにアクセスしたりできます。
攻撃者は任意のページにリダイレクトするURLを作成し、それをどこにでも拡散する可能性があります。
http://trusted.com/index.php?redirect=http%3A%2F%2Fmalicious.com
悪意のあるURLは、すべての文字をURLエンコードしてユーザーが検出できないように難読化され、%68%74%74%70%3A%2F%2F%6D%61%6C%69%63%69%6F%75%73%2E%63%6F%6D
のような文字列が得られます。
これで、ユーザーがサイトへの通常の安全なリンクのように見えるものをクリックすると、どこにでも移動する可能性があります。
ユーザーのログイン後にこれを行うと、質問で示唆したように、実際にページにログインして資格情報を入力すると、ユーザーが実際にサイトにいると信じるようになるため、さらに危険です。ログイン後に「間違ったパスワード、再試行」タイプのページを表示するのは簡単です。
Steffen Ullrichがこの質問に answer と私が this で別の質問に答えたときにすでに述べたように、PHP 5.1より古いバージョン) .2これはヘッダー挿入に使用できます。
多くの場合、解決策はホワイトリストに登録することです。 PHPの例:
$param = $_GET["redirect"];
$allowed = array(
"index" => "index.php",
"blog" => "blog/index.php",
// ...and so on...
);
$redirect = isset($allowed[$param]) ? $allowed[$param] : "index.php";
header('Location: '.$redirect);
リダイレクトしたいページがたくさんある場合、これは面倒です。 URLがどのように見えるかに応じて、自分のサイトのURLを検証できます。たとえば、それらがhttp://trutsted.com/?pageid=1234
の形式になっている場合は、ページングされたものだけを受け入れてリダイレクトし、それが実際に数値であることを確認できます。
自分のサイト内からリダイレクトリンクのみを機能させたい場合は、リクエストのHTTPリファラーの見出しを確認できます。 HTTPページとHTTPSページの両方にリンクしている場合、リファラーヘッダーが送信されないため、HTTPとHTTPSの両方でサイトを提供している場合、これはいくつかの問題に遭遇する可能性があります。
ここにいくつかのサンプルコードがあります:
$headers = Apache_request_headers();
$referer = isset($headers['referer']) ? parse_url($headers['referer'], PHP_Host) : "";
if($referer == "trusted.com") {
//Do the redirect. If you want your code to be safe on old PHP versions,
//you will need to filter out newlines or just URL encode the URL.
}
else {
//Inform the user of the problem or just redirect to your index page.
}
現在のバージョンのPHPヘッダー関数での改行インジェクションの検出と防止、 HTTPヘッダーインジェクションを回避する方法(改行文字) を参照)バージョンpf PHPあなたはおそらく次のようなことをすることができます
login.php?redirect=%0D%0A%0D%0A<script>...
ヘッダーから抜け出して、
Location:
<script>...
そして、スクリプトは、セッションハイジャックのためにセッションCookieにアクセスして転送するなど、必要なことをすべて実行できます。
これは、スクリプトが現在のPHPで安全であることを意味するものではありません。任意のURLへのリダイレクトは決して良い考えではないので、newURLをリダイレクトに期待するURLに制限する必要があります。
他の人が言ったことに追加するには:
リダイレクト先の一連の既知のURL(識別子にマップできる)がある場合、「リダイレクト」パラメーター値には既知の識別子のみを許可する方がはるかに優れています。次に、識別子を安全な既知のURLにマップできます。
このようなテクニックのおかげで、「すべての問題」が解消されます。
もちろん、URLの値がユーザーにとって100%任意である場合、またはすべての可能なURLのセットがない場合、これは適用できません。しかし、あなたのURLがあなたが制御している既知のページに対応しているなら、それのために進んでください!
私が考えることができる最初の脆弱性は、ユーザーをサイトの偽のコピーにリダイレクトする引数として完全なURLを渡すことです(login.php?redirect=http://malicious.com
)
それ以外にも、リダイレクトが発生して悪意のあるHTML/JavaScriptが表示されるのを防ぐ方法はいくつかあると思います。
原則として、any URLパラメータはサニタイズする必要があります。