web-dev-qa-db-ja.com

XSSに打ち勝つためのDOM要素のホワイトリスト

ご存知のとおり、開発者は、ユーザーが提供したデータをレンダリングまたは保存する前に、適切にエスケープ/検証する責任があります。ただし、何百もの単一の入力を忘れて、最終的にWebアプリケーションをXSSで悪用するのは比較的簡単であることに同意する必要があります。または、自分のサイトをXSSに悪用された人に会ったことはありませんか?

最近、TwitterやOrkutでさえXSSに苦しんでいます。そして、私は誰かを非難するためにここにいるのではありません。

ブラウザがDOM要素のホワイトリストをサポートしているとします。これらのホワイトリスト要素は、JavaScriptの実行が許可されている唯一の要素です。このような一般的なホワイトリストがある場合、優先するWebサイトを適切に機能させることは不可能であるため、正気に聞こえないことにすぐに気づきます。そして、あなたは正しいです!

ただし、HTMLおよびJavaScriptエンジンが、独自のWebサイトの要素をホワイトリストに登録できる構文をサポートしているとしましょう。例えば:

_<head>
    <script type="text/javascript">
        document.allowJavaScript(['div.item', '#list', 'a.navigate']);
    </script>
</head>
_

これは、DOMツリーの途中で_<script>_タグをレンダリングする問題を解決しませんが、これははるかに簡単に解決できると思います。

私の以前の点に加えて、説明されている解決策にはどのような問題や欠陥がありますか?

PDATE 1allowJavaScriptを呼び出すには、head要素のみを信頼する必要があります。

PDATE 2:うまくいけば、次のスニペットが私の考えをもう少し説明します:

_<html>
<head>
    <style>
        div.outer { background-color: #aaa; width: 200px; height: 100px; }
        div.inner { background-color: #5ff; width: 100px; height: 50px; }
        ul { list-style-type: none; }
        li { background-color: #bbc; border: 1px solid #fff; float: left;
            width: 100px; height: 30px; }
    </style>
    <script type="text/javascript">
        document.allowJavaScript(['div.outer', '#list', 'a.test']);
        function register_events() {
            var list = document.querySelector('#list');
            list.onclick = function() { alert('list'); }
            var example1 = document.querySelector('#list li:nth-of-type(1)');
            example1.onclick = function() { alert('example 1'); }
        }
        window.onload = register_events;
    </script>
</head>
<body>
    <div class="outer" onclick="alert('outer');">
        <div class="inner" onmouseover="alert('inner');">
        </div>
    </div>
    <a class="navigate" href="#" onclick="alert('a');">click me</a>
    <ul id="list">
        <li>example 1</li>
        <li>example 2</li>
    </ul>
</body>
</html>
_

これは以下の実行を許可すべきではありません:

  1. alert('inner')-> _div.outer_を許可しますが、その子要素は許可しません。
  2. alert('example 1')-> _#list_を許可しますが、その子要素は許可しません。
  3. alert('a')-> _a.test_ではなく_a.navigate_を使用できます。
13
jweyrich

ホワイトリストを<head>要素に制限しても、<title>は<head>の一部であり、多くの場合、ユーザー提供のデータが含まれているため、役に立ちません。したがって、ホワイトリスト定義は<head>の最初の要素である必要があり、最初のホワイトリスト呼び出しのみが受け入れられます。

この例では、<li>例1 </ li>のコンテンツは信頼されていません。したがって、攻撃者はこれを提供できます。

<li>example 1><a class="test" onmouseover="alert(document.cookie)">hello</a></li>

A.testがホワイトリストにあるため、コードが実行されます。厳密なdom要素の検証を適用することが可能です。ただし、<b>や<i>などのネストされた要素を許可したい場合があります。

許可されたタグと属性のホワイトリストに基づいて、信頼できないコンテンツを適切にエスケープする方がはるかに簡単です。

PS:CSSに埋め込まれたJavaScriptや、フラッシュやJavaなどのプラグインなど、他にも厄介な点があることに注意してください。

8

JavaScriptはクライアント側の言語です。

私の専門家の意見では、セキュリティを強化するためにクライアント側の実装を信頼することは時間の無駄であり、実装はリソースのかなりの無駄になります。

あなたの時間とお金は、サーバー側の環境で適切な入力のクレンジングと検証を実装することでより有効に活用されます。

14
Purge

Mozilla Securityの Content Security Policy(summary) の作業を見たことはありますか?

これは仕様です

コンテンツセキュリティポリシーは、Web設計者またはサーバー管理者がWebサイトでコンテンツがどのように相互作用するかを指定できるようにすることを目的としています。 XSSやデータインジェクションなどの種類の攻撃を軽減および検出するのに役立ちます。 CSPは防御の主要なラインを意図したものではなく、Webサイトを保護するために使用できる多くのセキュリティ層の1つです。

私は、CSPに過度に依存しないことを説明する条項を強調しました。

以下はポリシーの例です。

ポリシー定義の例

例1:サイトは、すべてのコンテンツを独自のドメインから取得することを望んでいます。

X-Content-Security-Policy: allow 'self'

例2:オークションサイトで、どこからの画像、信頼できるメディアプロバイダーのリストからのプラグインコンテンツ(コンテンツ配信ネットワークを含む)、サニタイズされたJavaScriptをホストするサーバーからのスクリプトのみを許可する必要があります。

X-Content-Security-Policy: allow 'self'; img-src *; \ object-src media1.com media2.com *.cdn.com; \ script-src trustedscripts.example.com

例3:サーバー管理者は、サイトのすべてのサードパーティスクリプトを拒否する必要があり、特定のプロジェクトグループは他のサイトからのメディアも禁止したい(sysadminsによって提供されるヘッダーとプロジェクトグループによって提供されるヘッダーの両方が存在する):

X-Content-Security-Policy: allow *; script-src 'self' X-Content-Security-Policy: allow *; script-src 'self'; media-src 'self';

ヘッダーにセキュリティポリシーを設定するように見えますが、攻撃に耐えることはできませんが、セキュリティポリシーを変更できるDOMにインラインで追加するよりもはるかに難しくなります。

あなたのアイデア/質問は考えるのに良いものだと思いますが、ますます包括的なものを作り始めると、正しく行うには費用がかかりすぎるという点が出てきます。

ページがSSLで保護されている場合、すべてのリソースすべきがSSL経由で提供されるのがいらいらすることに気づいたとき、私は同様の考えを持っていました。私が最初に考えたのは、SSLページでの読み込みが許可されている各リソースのチェックサムを用意することです(それらをクリアテキストで読み込むと、キャッシュしやすくなります)。もちろん、それを行うにはセキュリティに関する多くの問題があり、最終的には、セキュリティの問題と複雑さによってパフォーマンスの向上はすぐに失われるという結論に達しました。 DOMホワイトリストが同じようにすぐに影響を受けることがわかります。

1つの最後のポイント:ブラウザ側でホワイトリストを作成するための十分な知識がある場合、送信する前に、提供するデータのホワイトリストを実行できないのはなぜですか?ブラウザに?

10
Bradley Kreider

それは私には興味深いアイデアのように見えますが、あなたはそれに関する問題について尋ねているので、私は明白なもののいくつかで対応します。ほとんどのサイトにこれをグローバルに適用する方法はわかりません。ほとんどのサイトで、コア機能に使用できる危険なJavaScript関数の多くが必要と思われるためです。例えば。 onmouseover、href = "javascript:alert(1)"など。これを Caja または JSReg 、または JSandbox の代わりとして使用するには= DOMのどのレベルでも適用できる必要がある場合があります。たとえば、<div name="untrusted">のコンテンツを保護したいだけの場合です。

8
Weber

XSSは通常、外部のJavaScriptを信頼済みページの本文に挿入することで機能します。 document.allowJavaScript(['div.outer', '#list', 'a.test']);と書かれているコードを信頼する場合、XSSの脆弱性によって生成されるdocument.allowJavaScript(['div.evil', '#securityhole', 'a.exploit']);と言っているサイトの他のページのコードをどのように信頼しませんか?両方が同じページの同じコンテキストにある限り(これがXSSの主な考え方です)、一方を他方から識別する方法はありません。

もちろん、「特権」コンテキスト-<head>内-および「非特権」コンテキスト<body>-があると言うこともできます。これは脆弱性の一部をカバーしますが、すべてではありません。ページの「特権」部分にコンテンツを挿入できるXSSの脆弱性がないことを保証する方法がないためです。もちろん、それらはそれほど頻繁ではありませんが、問題全体を解決するわけではありません。サーバーで検証を行う必要があります。

さらに、メンテナンスの問題が発生します-デザイナーがページ上の何かを変更するたびに、特権要素リストを編集する必要があり、同時に「動的」な部分を常に除外する必要があります。実際のプロジェクトでは、これを行うのはかなり難しいかもしれません。特に、一部のページは、アプリケーションの別々の部分によって生成される多くの独立したウィジェットで構成されているため、まったく異なるチームで作成できます。

7
StasM

ご興味をお持ちでしたら、 Ter LouwとVernkatakrishnanの青写真Dan KaminskyのInterpolique 、およびMozillaコンテンツセキュリティポリシーをお読みになることをお勧めします。 context-aware auto-escapingGoogleのctemplateに実装されている も確認してください。多くの素晴らしい前の仕事があります:あなたが車輪を再発明しないことを確認してください。

ブループリントとBEEPに関する以前の研究では、インラインセキュリティポリシーのリスク(提案の場合と同様)は、XSSインジェクションが攻撃者に新しいポリシーのインジェクトを許可する可能性があることを示しています。攻撃者が新しいHEADタグを挿入し、その中にallowJavaScriptを呼び出すスクリプトを追加するとどうなりますか?

以前の研究でも、悪意のあるJavascriptの実行を停止するだけでは安全ではないことが示されています。攻撃者がHTMLページに任意のものを挿入できる場合、攻撃者は次のことができる可能性があります。ユーザーをフィッシングするか、認証資格情報を盗みます(ユーザーにユーザー名とパスワードを要求するログインフォームを追加することを考えますが、フォームアクションは攻撃者のサイトに送信されます)、(iv)CSRF攻撃をマウントします(インラインイメージまたは被害者のサイトにURLを自動的にロードする、またはユーザーをだましてしまうフォーム要素)(v)クリックジャッキング/ストロークジャック攻撃(一部はJavascriptを必要としない)。

以前の研究でも、CSSを攻撃することにより、JavaScriptを実行しなくても攻撃が可能であることを示しています。 CCS 2010のHuang、Weinberg、Evans、Jacksonによる論文を参照してください。少なくとも一部のブラウザーで、ドキュメントに挿入ポイントが存在する場合、スキームはこれに対して脆弱になる可能性があります。

最後に、DOMの要素をホワイトリストに登録している場合、悪意のあるデータがホワイトリストに登録された要素のコンテキストに入るまで、HTMLページにアイテムを挿入する攻撃者がタグを開いたり閉じたりするのを防ぐにはどうすればよいですか?たとえば、ポリシーで、スクリプトがBODYの下の1番目のDIVの下の2番目のPタグで許可されている場合、最初のPタグの直後に挿入ポイントがあると、攻撃者は</P><P><DIV><SCRIPT>alert('nasty')</SCRIPT>を挿入できます、そして今度は攻撃者の厄介なスクリプトがブラウザによってページのホワイトリストに登録された部分の一部として扱われます。

全体的な推奨事項:この防御策に依存することはお勧めしません。これには多くの弱点があります。

6
D.W.

非常によく似た質問がありましたが、(今のところ)突破の可能性がないため、誰かがあなたの質問を指摘しました。
https://stackoverflow.com/questions/5821985/would-this-be-a-good-idea-against-xss

多分一緒に私たちは良い解決策を見つけます;)

1
mgutt