web-dev-qa-db-ja.com

ユーザーが生成したHTMLのセキュリティリスク?

HTMLコンテンツをアップロードできるウェブサイトを作成しています。

現在これらは禁止されているタグです:

<script></script>
<iframe>
<object>
<embed>
<style></style>
All on= attributes, i'm not gonna list them all there are like 70 of them

ユーザーがJavaScriptを使用したり、ページ上の他のタグに影響するコードを配置したりしたくないので、スタイルタグも使用しません。

ユーザーがページ上の他のものに影響を与えることなくHTMLを生成できるようにするときに注意する必要がある他のタグはありますか?

38
Jevon

ユーザー定義のHTML

許可したくないものをブラックリストに登録して、ユーザー入力を無害化しようとしています。残念ながら、特にHTML5のオプションの非常に大きなリストを考えると、何かを見落とすことは非常に簡単です。何かが欠けていると、潜在的に危険なXSSの脆弱性が発生しますが、これは実際には必要ありません。私の頭の上からいくつかのランダムな例を選ぶには:

  1. SVGタグが(限られた)状況でスクリプトを実行できることを知っていますか?
  2. 禁止したonイベント属性のリストで、廃止された(まだ使用可能な)Marqueeタグのonbounceイベント属性を確認して取得しましたか?
  3. 危険なタグ/イベントを追加する可能性がある場合に備えて、今後X年間に展開される可能性のあるHTML仕様への変更を確認して追跡しますか?

非常に多くの問題があり、ブラックリストで入力を保護することはほぼ不可能です。さらに、あなたは間違った視点から問題に取り組んでいます。セキュリティ上、最初にしたいアプローチは 最小権限の原則 です。 「ユーザーに何をさせないようにすべきか」と尋ねるよりも、「ユーザーに何をさせればよいか」と尋ねる方がはるかに安全です。したがって、2つのステップのプロセスが必要です。

1。堅牢なパーサー。非常に堅牢なパーサーが必要です。ブラウザはHTMLの解析に関して非常に寛容であるため、これは驚くほど困難です。攻撃者が悪いHTMLを提供し、パーサーが試行を停止して「ここにはHTMLがない-あなたは安全です!」と言ったが、ブラウザは同じ入力を受け取り、HTMLの想定を推測して終了した場合悪意のあるものに直面すると、XSSの脆弱性があります。これは、HTML入力を処理するときにブラウザーによって異なる「修正」が適用される可能性があり、HTMLを確実に解析するというすでに困難なタスクをさらに困難にするため、さらに難しいと言えます。

ブラウザーがHTMLで高速に再生する例として、このHTMLをファイルに保存してブラウザーに読み込むことができます。

<table><img src="1" <table onerror="alert(1)"
<p>hi</p></table>

Chrome=でロードし、ページの要素を検査すると、ブラウザが実際にこれをレンダリングしたことがわかります(おそらくバージョンによって異なります)。

<img src="1" <table="" onerror="alert(1)" <p="">hi<p></p><table></table>

これは、アクティブなXSSペイロード(tableタグとpが意味のない属性に変わったという事実によって少し難読化されています)を含むイメージタグ、リテラル文字列hi、空のpタグと空のtableタグ。最終結果は入力とはかなり異なります。ペイロードを隠そうとはしませんでしたが、yourパーサーは同じように理解しましたか? imgタグ内にないものは技術的に不正であるため、おそらくパーサーはtableタグ内のtdタグを無視しようとしたでしょう。多分あなたのパーサーは<tableimgタグ内にあり、onerrorを無視しました。テーブルタグには技術的にイベントがないためです。しかし、結局のところ、ブラウザが私のJavaScriptペイロードを実行することを妨げるものはありませんでした。あなたのパーサーはそれをキャッチしたでしょうか?

2。ホワイトリストに許可されたタグと属性ユーザーのHTMLを解析したら、ブラックリストと比較して、許可されていないタグ/属性を削除する必要はありません。代わりに、ホワイトリストと比較して、安全であると特に確認および承認されていないものを削除します。これにより、セキュリティが大幅に強化されます。正直に言って、ユーザーに本当にMarqueeタグを使用させますか?

最も重要なことですが、堅牢なHTMLパーサーを構築することは驚くほど困難です。あなたがそれを自分でやろうとすると、あなたは多くの時間を費やし、おそらく多くの間違いを犯すでしょう。通常の状況では、十分にサポートされているサードパーティのライブラリを見つけて使用する方がはるかによいでしょう。

代替提案

私が通常推奨する別の戦術は、ユーザーがHTMLをまったく使用できないようにすることです。むしろ、より限定された言語を許可します(スタックオーバーフローで質問と回答を書くために使用される markdown など)。より限定された言語仕様により、パーサーの記述がはるかに簡単になり、エラーが発生しにくくなり、マークダウンをHTMLに変換するプロセスにより、「安全性」を保証することが容易になります(注:保証されていないが簡単-マークダウンからHTMLへのコンバーターは、時々XSSに悩まされます脆弱性)。ユーザーが持つ書式設定オプションの種類が制限されるというわずかな欠点があります(ただし、ほとんどの状況では実際にはその欠点を考慮していません)が、マークダウンパーサーとHTMLコンバーターが幅広いで利用できるという素晴らしい利点もあります。さまざまな言語。このようなより限定されたオプションは、通常、ユーザビリティとセキュリティの間の適切なトレードオフです。ユーザーのマークダウンを構築するWYSIWYGエディターを追加することもできます。

86
Conor Mancone

現在これらは禁止されているタグです:

既に投稿されている内容に加えて、禁止が「ユーザーにデータの保存を許可しない」notであることを確認してください。 = "禁止されているものを削除して残りを保存します"

例:

Input:
Hi there, here is my <script>alert('scary script')</script>, will I be shown?  
Filtered:  
Hi there, here is my alert('scary script'), will I be shown?

禁止されたタグを削除するだけでいいようです?結局のところ、愚かなことをするスクリプトタグを停止しました。しかし、代わりにこれを入力するとどうなりますか?

Input:  
Hi there, here is my <scr<script>ipt>alert('scary script')</scr<script>ipt>, will I be shown?  
Filtered:  
Hi there, here is my <script>alert('scary script')</script>, will I be shown? 

おっと! <script>タグを削除すると、私の文字列は有効な攻撃になりました。

私はこのトリックを使用して、長い間忘れられていたソーシャルネットワーク上でかっこいい外観のプロフィールページを作成し、カスタムHTMLを追加できるようにしました。 HTMLのフィルタリングはhardです。目的を達成する他の方法を見つけてください。

21
Matsemann

私がXSSをこのブラックリスト(他の回答で主に取り上げた)を超えてすり抜ける可能性があるすべての方法は別として、任意のHTMLを許可することは依然として非常に危険です。たとえば、ユーザーがstyle=属性(スタイルタグをブロックしたが、インライン属性については何も言わなかった)、またはレガシー位置属性にアクセスできる(ユーザーにHTMLの提供を許可している場合、ブラウザーは多少無効な入力を許可する必要がある) 、攻撃者は基本的に、フィッシングログインフォーム、(偽の)セキュリティ警告/ランサムウェアの恐喝メッセージ、恐ろしい画像やビデオなどの悪意のあるコンテンツでページ全体を上書きすることができます。悪意のあるユーザーは、ブラウザのブラウザに悪影響を及ぼすHTMLを見つけることもできます。レンダリングエンジン(RAMを大量に消費する、および/またはすべてのCPUをレンダリングして使用するために永遠にかかる;すべての攻撃がシステムの制御を狙っているわけではない)およびそのHTMLをどこにでもスパムするできる。

唯一の適切なオプションは、十分にテストされたライブラリーによってHTMLに翻訳される安全なレイアウト言語を使用することです(さまざまな形式のマークダウンまたはbbcodeがこれを目的としています)。 HTMLを許可する必要がある場合は、特定のタグをホワイトリストに登録し、それらのタグ内で特定の属性をホワイトリストに登録し(必要に応じて、これらの属性の特定の値のみを許可)、一致しないものをすべて破棄します。次に、フィルターを変更するたびに再テストして、フィルター自体の変更が悪意のある入力を引き起こしていないことを確認します。

6
CBHacking

解釈/解析されて公開されるユーザー生成コンテンツには大きなリスクがあります。 XSS攻撃などは、ユーザーがサニタイズ機能を介してタグをこっそりと盗むことができるために発生する可能性があり、ブラウザーが設計する必要があると解釈するバリエーションはたくさんあります。

勧告?タグを一切許可しません。必要に応じて、これを試行するライブラリがサーバー側にあり、存在する可能性のあるサニタイズバイパスを回避するために多くの作業が行われる可能性があります。

あなたの質問に関して:

ユーザーがページ上の他のことに影響を与えることなくhtmlを生成できるようにするときに注意が必要な他のタグはありますか?

最善のアプローチは、すべてのタグが問題であると想定することです。さらに、必要な特定のタグを決定します(ユーザーGhedipunkが提案したとおり)。これは、タグが独自の方法で、時には予期しない方法で悪用される可能性があるためです。これは、特定のブラウザ実装の癖から、あまり一般的でないタグの使用まで、さまざまです。特定のタグを除いて、HTMLタグのパターンに従うすべての入力を削除する方が、特定のタグを回避するよりもはるかに簡単です。

これを実現するには、最も単純な方法からはるかに高度な方法(実際のDOM処理)まで、さまざまな方法があります。ブラックリストアプローチを実行しようとすると、さまざまなバイパス攻撃のバリエーションや、安全と考えるか含めるのを忘れたさまざまなタグの予期しない使用を常に追跡することになります。

そのような操作がより高度で安全な方法で行われたライブラリがすでに存在していると私は確信しています。私が推奨するのは、開発しているプラ​​ットフォームに関係なくそれらを探すことです。

5

ページレイアウトに問題が発生しない場合は、ユーザーが生成したコードを<iframe>内に配置し、別のサブドメインまたはドメインから提供することをお勧めします。

<iframe>は、フレームの内側のコンテンツをフレームの外側のページから分離するように設計されています。別のドメインからフレームコンテンツを提供することで、メインサイトが使用しているCookieからフレームコンテンツを分離することもできます。メインドメイン(example.com)からのCookieはサブドメイン(foo.example.com)にも表示されますが、メインサイトが異なるサブドメイン(www.example.com)または完全に異なるドメイン(example2.com)にある場合、サイトは異なるクッキーを持っているでしょう。

欠点は、フレームのコンテンツを周囲のページとシームレスにマージすることが困難であり、たとえば、フレームを表示するための個別のスクロールバー。

1
jpa

これにより、クロスサイトスクリプティング(XSS)と呼ばれる攻撃ベクトルが発生する可能性があります here 。進化し続けるHTML言語ではタグのリストを迂回する方法がたくさんあるので、タグのリストをブラックリストに載せることに依存/信頼すべきではありません。

経験則は、サンドボックス環境を使用し、入力を無害化し、出力をエンコードします。両端(クライアント側とサーバー側)には、このようなタスクを実行できるさまざまなソリューションとフレームワーク DOMPurify があります。

0
avicoder