26

私が見たすべてから、(XSS を防ぐ目的で) ユーザーが入力したコンテンツで html をエスケープするための規則は、コンテンツをレンダリングするときにそれを行うことのようです。ほとんどのテンプレート言語はデフォルトでそれを行うようです。このロジックはプレゼンテーション層の仕事であると主張するこのスタックオーバーフローの回答のようなものに出くわしました。

だから私の質問は、なぜこれが当てはまるのですか?次の理由により、データベース内のすべてのものをページに安全に表示できるという前提の下で作業できるように、入力 (つまり、フォームまたはモデルの検証) でエスケープする方がクリーンに思えます。

  1. さまざまな出力形式 - 最新の Web アプリの場合、サーバー側の html レンダリング、AJAX/JSON を使用する JavaScript Web アプリ、および JSON を受信するモバイル アプリを組み合わせて使用​​している場合があります (一部の Web ビューがある場合とない場合があります)。これは、JavaScript アプリまたはサーバーでレンダリングされた html の場合があります)。そのため、いたるところで html エスケープに対処する必要があります。ただし、入力は常にモデルとしてインスタンス化 (および検証) されてから db に保存され、モデルはすべて同じ基本クラスから継承できます。

  2. コードインジェクション攻撃を防ぐために、入力にはすでに注意する必要があります (これは通常、ORM または db カーソルに抽象化されますが、それでもなお)、ここで html エスケープについても心配しないでください。何も心配する必要はありません。出力のセキュリティ関連?

ページ レンダリングでの html エスケープが好まれる理由についての議論を聞きたいです。

4

2 に答える 2

42

すでに書かれていることに加えて:

  • さまざまな出力形式があり、それらすべてに HTML エスケープが必要になるとは限りません。JSON API を介してデータを提供している場合、クライアントがそれを HTML ページまたはテキスト出力 (電子メールなど) に必要とするかどうかがわかりません。Jack & Jill"Jack & Jill" を取得するためにクライアントに " " をアンエスケープするように強制する必要があるのはなぜですか?

  • デフォルトでデータが破損しています。

    • 「amp」でキーワード検索すると、「Jack & Jill」が表示されます。なんで?データを破損したためです。

    • 入力の 1 つが URL: であるとしますhttp://example.com/?x=1&y=2。この URL を解析し、y存在する場合はパラメーターを抽出します。URL が に壊れているため、これは黙って失敗しますhttp://example.com/?x=1&y=2

  • それを行うのは単に間違ったレイヤーです.HTML関連のものは生のHTTP処理と混同されるべきではありません. データベースは、1 つの可能な出力形式に関連するものを格納するべきではありません。

  • XSS と SQL インジェクションだけがセキュリティの問題ではありません。ファイルシステム (Web サーバーにコードを実行させる「.php」などの拡張子を考えてください) や SMTP (改行文字を考えてください) など、扱うすべての出力に問題があります。他の数。「入力時にセキュリティを処理してから忘れる」ことができると考えると、セキュリティが低下します。むしろ、入力データを信頼しない特定のバックエンドにエスケープを委任する必要があります。

  • 「いたるところに」HTMLエスケープを行うべきではありません。バックエンドのエスケープと同様に、それを必要とするすべての出力に対して正確に1 回実行する必要があります。SQL の場合、SQL エスケープを 1 回行う必要があります。SMTP などでも同じことが言えます。通常、エスケープを行うことはありませ。それを処理するライブラリを使用します。

    賢明なフレームワーク/ライブラリを使用している場合、これは難しくありません。Web アプリで SQL/SMTP/HTML エスケープを手動で適用したことはなく、XSS/SQL インジェクションの脆弱性もありません。Web ページを作成する方法でエスケープを適用することを覚えておく必要がある場合、または最終的に脆弱性が発生する場合は、それが間違っています。

  • form/http 入力レベルでエスケープを行っても、安全性は保証されません。データが別のルートからデータベースやシステムに入らないことを保証するものは何もないからです。システムへのすべての入力が HTML エスケープを適用していることを手動で確認する必要があります。

    他にインプットがないと言うかもしれませんが、システムが成長したらどうなるでしょうか? 多くの場合、戻って決定を変更するには遅すぎます。これは、この時点までに大量のデータがあり、データが HTML エスケープされていることをすべて期待しているパブリック API などの外部インターフェイスとの互換性がある可能性があるためです。

  • システムへの Web 入力でさえ安全ではありません。別のエンコーディング レイヤーが適用されることがよくあるためです。たとえば、エントリ ポイントで base64 でエンコードされた入力が必要になる場合があります。自動 HTML エスケープでは、そのデータ内にエンコードされた HTML がすべて失われます。そのため、もう一度HTML エスケープを行う必要があります。忘れずに行い、どこでエスケープしたかを追跡してください。

ここでこれらを拡張しました:http://lukeplant.me.uk/blog/posts/why-escape-on-input-is-a-bad-idea/

于 2012-12-14T11:43:25.293 に答える
26

元々の誤解

出力のサニテーションと検証を混同しないでください。

<script>alert(1);</script>完全に有効なユーザー名ですが、Webサイトに表示する前に必ずエスケープする必要があります。

そして、そうです、 「ドメインビジネスロジック」とは関係のない「プレゼンテーションロジック」のようなものがあります。そして、プレゼンテーションロジックはプレゼンテーション層が扱うものです。そして特にインスタンス。適切に記述されたMVCでは、ビューは本格的なオブジェクトであり(RoRが通知しようとするものとは異なります)、Webコンテキストに適用すると、複数のテンプレートを調整します。View

あなたの理由について

さまざまな出力形式は、さまざまなビューで処理する必要があります。HTML、XML、JSON、およびその他の形式を管理する規則と制限は、それぞれの場合で異なります。

誰かがいつかそれを編集する必要があるかもしれないので、あなたは常に元の入力を保存する必要があります(準備されたステートメントを使用していない場合、インジェクションを避けるために消毒されます)。

また、オリジナルとxssセーフの「パブリック」バージョンを保存するのは無駄です。毎回サニタイズするにはリソースが多すぎるため、サニタイズされた出力を保存する場合は、すでに間違ったツリーに腹を立てています。これは、データベースを汚染する代わりにキャッシュを使用する場合です。

于 2012-06-28T22:24:53.837 に答える