web-dev-qa-db-ja.com

検証なしで直接window.location.hrefを使用することは安全ですか?

検証なしでwindow.location.hrefを使用することは安全ですか?

例えば:

<script>
    var value = window.location.href;
    alert(value);
</script>

上記の例から、クロスサイトスクリプティング(XSS)攻撃に対して脆弱ですか?もしそうなら、どのように?攻撃者はwindow.location.hrefの値を悪意のあるコンテンツに変更する方法を教えてください。

編集(2番目の状況)

これはURLです:www.example.com?url=www.attack.com

検証なしで値を返すgetQueryString()関数があると仮定してください。

<script> 
    var value = getQueryString('url'); 
    window.location.href = value; 
</script>

同じ質問ですが、クロスサイトスクリプティング(XSS)攻撃に対して脆弱ですか?もしそうなら、どのように?攻撃者は「window.location.href = value」を使用してXSSを実行する方法を教えてください。

15
overshadow

location.hrefを使用すると、次の2つのことを理解できます。

  1. location.hrefの値をコードで渡して操作し、それを操作して、コードのロジックをガイドするために使用します。
  2. location.hrefにsometingを割り当てると、ブラウザーが別のURLに移動します。

最初の値は値を使用しており、安全と見なすことができます。 location.hrefの値は文字列にすぎません。もちろん、これはユーザー入力の一部なので、evalステートメントに渡したくありませんが、それは他のすべての形式のユーザー入力にも当てはまります。実際、location.hrefの値は常に有効なURLであるため、そのコンテンツについて特定の仮定を行うことができます。その意味で、ほとんどの形式のユーザー入力よりもより安全であると主張できます。間違った仮定をしない限り。

2つ目は注意が必要なものです。検証されていない値を割り当てると、フィッシングに使用できるオープンリダイレクトにつながる可能性があります。さらに、javascript:およびvbscript: URIの使用からXSSの問題が発生します。


編集:リクエストに応じて、以下はlocation.hrefへのアクセスに関する問題の詳細な説明です。

攻撃者が制御する変数fooがあるとします。ソースは本当に何でもかまいませんが、クエリ文字列パラメーターが良い例です。 fooの値をlocation.hrefに割り当てると、どうなりますか?さて、ブラウザはその値をURIとして解釈するために最善を尽くし、ユーザーを結果のアドレスにリダイレクトします。ほとんどの場合、これによりページの読み込みがトリガーされます。例えばvalue"https://www.google.com/"の場合、Googleのフロントページが読み込まれます。ユーザーの操作なしでそれを可能にすることは オープンリダイレクト と呼ばれ、セキュリティの脆弱性と見なされます!

ただし、ページのロードをトリガーしないタイプのURIがあります。そのようなURIの一般的な例は、フラグメント識別子のみを含むものです。 #quux。これをlocation.hrefに割り当てると、ページがID "quux"の要素までスクロールし、他には何も実行されません。フラグメントのURIは、フラグメントの値自体で何も愚かなことをしない限り安全です。

次に、興味深い部分:javascript:およびvbscript: URI。これらはあなたを噛むものです。 JavaScriptおよびVBScriptのURIスキームは、現在開いているWebページのコンテキストでコードを実行するために使用できる非標準のURIスキームです。悪いですね。そうですね。攻撃者が制御する変数fooについて考えてみましょう。ユーザーに対する攻撃を開始するために攻撃者がしなければならないことは、変数にスクリプトURIを挿入することだけです。これをlocation.hrefに割り当てると、スクリプトでevalを呼び出すのと基本的に同じになります。

JavaScript URIはすべての最新のブラウザーで機能しますが、VBScriptはIEのみであり、ページを互換モードでレンダリングする必要があります。

最後に、考慮すべきもう1つの興味深いURIスキームがあります。それはデータURIです。データURIはファイルリテラルです。ファイル全体がURIとしてエンコードされます。 HTML文書を含む、あらゆるファイルのエンコードに使用できます。また、これらのドキュメントには、他のドキュメントと同様にスクリプトを含めることができます。

ほとんどのブラウザは、各データURIを独自の一意の Origin として扱います。つまり、データURIでラップされたHTMLドキュメント内のスクリプトは、他のページのデータにアクセスできません。 Firefoxを除く。

FirefoxはデータURIを他のすべてのブラウザとは少し異なって扱います。その中で、データURIは継承開いているドキュメントのオリジンを継承します。つまり、どのスクリプトも参照ドキュメントに含まれているデータにアクセスできます。これがXSSです。

20
jupenur

XSSは#1では不可能です

私が考えることができる最悪のケースは、ソーシャルエンジニアリングにそれを使用している誰かです(ドメインがEbayやAmazonのように非常に人気があるとしましょう)。 URLを使用して http://haxor.site "に移動し、それを誰かに送信します。

しかし、それでも危険だとは思いません。URLエンコードが原因で、メッセージがかなり乱雑に見えるからです。

編集:私がこの質問に答えたときに「#2」がなかったので、これは#1のみの答えです

1
Jhuliano Moreno
var value = getQueryString('url'); 

window.location.href = encodeURI(value); 

これが一番簡単な方法だと思います

0
wushang