web-dev-qa-db-ja.com

ユーザー生成HTML内のJavaScriptインジェクション攻撃を防ぐ方法

ユーザーが送信したHTMLを(データベースに)保存しています。 Javascriptインジェクション攻撃を防ぐ必要があります。私が見た中で最も有害なのは、style = "expression(...)"のスクリプトです。

これに加えて、かなりの量の有効なユーザーコンテンツには特殊文字とXML構成要素が含まれるので、可能であればホワイトリストアプローチを避けたいと思います。 (許可されるすべてのHTML要素と属性のリスト)。

JavaScript攻撃文字列の例は次のとおりです。

1)

「こんにちは、<dog>要素に<script> alert( "bad!")</ script>の問題があります... "

2)

「こんにちは、この<b style = "width:expression(alert( 'bad!'))">犬</ b>は黒です。」

そのようなJavascriptを防止し、残りをそのままにする方法はありますか?

私がこれまでに持っている唯一の解決策は、正規表現を使用して特定のパターンを削除することです。ケース1は解決しますが、ケース2は解決しません。

編集:申し訳ありませんが、環境について言及するのを忘れました-それは本質的にMSスタックです:

  • SQL Server 2005
  • C#3.5(ASP.NET)
  • Javascript(明らかに)とjQuery。

チョークポイントをASP.NETレイヤーにしたいと思います-誰でも悪いHTTPリクエストを作成できます。

編集2:

皆さん、リンクをありがとう。リストを定義できると仮定すると(彼のコンテンツには多くの数学およびプログラミングの構成要素が含まれるので、ホワイトリストは非常に迷惑になります)、私はまだここに質問があります:

どのような種類のパーサーを使用すると、「不良」な部分を削除できますか?悪い部分は要素全体かもしれませんが、属性にあるこれらのスクリプトについてはどうでしょう。 <a hrefs> willy-nillyは削除できません。

52

あなたはそれだと思いますか? チェックアウト

どのアプローチをとるにせよ、間違いなくホワイトリストを使用する必要があります。それはあなたがあなたのサイトで許可していることについて安全であることに近づくための唯一の方法です。

[〜#〜] edit [〜#〜]

残念ながら、.NETには慣れていませんが、XSSとのstackoverflowの戦いを確認できます( http://blog.stackoverflow.com/2008/06/safe-html-and-xss/ =)およびこのサイトに投稿されたHTMLを解析するために書かれたコード: Archive.org link -ホワイトリストが大きいので、これを変更する必要があるかもしれませんが、それで開始できます。

36

私の意見では、要素と属性のホワイトリストはonly許容可能な選択肢です。ホワイトリストにないものはすべて削除するかエンコードする必要があります(エンティティへの<>& "の変更)。また、許可する属性内の値を確認してください。

それ以下で、既知のエクスプロイトまたは将来発見されるエクスプロイトの問題に自分自身を開放しています。

7
BarelyFitz

本当に安全な唯一の方法は、ホワイトリストを使用することです。すべてをエンコードしてから、許可されたコードを元に戻します。

危険なコードのみを許可しないというかなり高度な試みを見てきましたが、それでもまだうまくいきません。 everythingを安全にキャッチしようとするのはかなりの偉業であり、誰もが考えることができます。

4
Guffa

基本的には、Paoloが言ったように、ユーザーがしてはいけないことを除外しようとするのではなく、ユーザーに許可されていることに焦点を合わせるべきです。

許可されたHTMLタグ(b、i、u ...など)のリストを保持し、他のすべてを除外します。また、許可されたHTMLタグのすべての属性を削除することもできます(たとえば、2番目の例のため)。

別の解決策は、いわゆるBBコードを導入することです。これは、多くのフォーラムで使用されています。 HTMLに似た構文を持っていますが、許可されたコードのホワイトリストのアイデアから始まり、それがHTMLに変換されます。たとえば、[b] example [/ b]は次のようになります 。 BBコードを使用してHTMLタグを事前にフィルタリングする場合は、事前に確認してください。

3
Aistina

現在、最善のオプションは、コンテンツセキュリティポリシーヘッダーを使用することです。

Content-Security-Policy: default-src 'self';

これにより、インラインスクリプトと外部スクリプト、スタイル、画像などの両方が読み込まれないため、同じOriginのリソースのみがブラウザによって読み込まれて実行されます。

ただし、古いブラウザでは動作しません。

2
Adam

どのサーバー側コードを使用していますか?悪意のあるスクリプトを除外できる数または方法がありますが、危険な領域です。熟練した専門家でさえもキャッチされます: http://www.codinghorror.com/blog/archives/001167.html

0
Chris Simpson