2017-07-19 3 views
6

アプリケーションで.NET Framework(.NET Framework 4.5.2を対象とする)によって提供されるSystem.Web.Security.AntiXss.AntiXssEncoderクラスを使用していますが、アラビア文字を含むフィールドに関する問題が発生しています。アラビア文字がAntiXssEncoderによって再エンコードされないようにするにはどうすればよいですか?

次のコンソールアプリケーションでは、我々が持っている問題を示しています

using System; 
using System.Collections.Generic; 
using System.Web.Security.AntiXss; 

namespace EncodingTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var source = new List<string> { "Hello World", "على", "blöd", "&#1575;&#1604;&#1605;" }; 

      foreach (var testString in source) 
      { 
       var antiXssEncoded = AntiXssEncoder.HtmlEncode(testString, false); 
       Console.WriteLine($"{testString} => {antiXssEncoded}"); 

       Console.WriteLine(); 
      } 

      Console.ReadKey(); 
     } 
    } 
} 

2番目のリスト項目でアラビア語の文字が正しくエンコードされますが、前後の要素で既にエンコードされた文字は、エンコーダを通過している場合は、 '&'文字は2回目に&amp;にエンコードされ、次にウェブページに正しく表示されません。

アプリケーションからのこの出力は、(エンコードされていないアラビア文字がコンソールに「???」と表示される)、これを示しています

Hello World => Hello World 

??? => &#1593;&#1604;&#1609; 

blöd => blöd 

&#1575;&#1604;&#1605; => &amp;#1575;&amp;#1604;&amp;#1605; 

はこれを防ぐ方法はありますか?

現在、ユーザ入力を受け取り、データベースに保存する前にエンコーダで渡します。このエンコードされたデータはフロントエンドに送信され、表示されます。ユーザーが文字列を編集し、それを私たちのバックエンドに戻すと、それを保存する前に再度エンコードするので、アンパサンドで問題が発生します。

他の質問については、入力時にユーザー入力をデータベースに保存してから、表示用に送信する前にエンコーダを通過させる必要があるとの意見がありました。私たちはこれを行うことができましたが、データが出力されるすべての場所でこれがコード化されていることを確認する必要がありました。編集されたデータがフロントエンドから戻ってくるという問題には役に立たないでしょう。データがエンコードされているかどうかはまだ分かりませんし、次に表示されるときにエンコードするだけです。

エンコーダに&#1575;のような文字を再エンコードしないようにする方法はありますか?&amp;#1575;に入力するか、何か間違っているだけですか?

+0

文字列がエンコードされているかどうかを常に知っておく必要があります。ダブルエンコーディングの問題を防ぐ唯一の方法は、エンコードすることがわかっている文字列を再エンコードしないことです。もちろん、データベース*には、エスケープされていない生の値が含まれているべきです。なぜなら、代わりに、あなたが "على"を調べようとしているときにデータベースコードがHTMLエンコーディングについて突然知っていなければならないからです。表示と転送のために文字列を正しくエンコードすることは、常にフロントエンドの責任です。 –

+1

ありがとう@jeroenmostert - これは理にかなっており、私たちがやっていることは間違っている –

答えて

0

これは予期された動作であり、防止しないようにしてください。

通常、HtmlEncodeに渡される文字列は、プログラムのユーザーによって提供され、メソッドに渡される正確な方法でHTMLで表示されるようになります。これはすべて&(および同様の場合)をエンコードする必要があることを意味します。例えば。ユーザーが"use '&amp;' to represent '&' in HTML"のようなものを入力した場合、レンダリングされたHTMLには"use '&' to represent '&' in HTML"が実際には届きません。問題にアプローチする方法

あなたは本当に使用している文字列のコンテンツのエンコーディングが何であるかを知っている必要があります。文字列がHTMLエンコードされているかどうかを何度も何度知っているかは絶対にありません。同じことがurlエンコーディング(?q=search%20alotのような%エンコーディング)とJavaScript文字列値エンコーディング(I said \"Hi Matt\"\nin this is long & winded postなど)にも適用されます。

これは、一貫性のあるエンコードでストリングを格納するか、各ストリング(つまりDB内の次の列)とともにスティッキングに適用されるエンコードのタイプを格納する必要があることを意味します。 「これはプレーンテキストでエンコードされていない」、「これはHTMLを墨塗りして準備ができています」、「これはユーザーによって提供された生のHTMLで、墨塗りされていない」、「これはJavaScript文字列としてコード化されたプレーンテキスト(\nを使用) "。

文字列を「HTMLをレンダリングする準備ができている、HtmlEncodeしない」と誤って分類する重大な危険があります。不正なユーザーの入力をHTMLとして簡単にレンダリングしてクロスサイトスクリプティング(XSS)脆弱性を引き起こす可能性があります。あなたが持っているオーバーエンコーディングの振る舞いはより安全です。また、無駄な出力を生成する可能性があります。そのため、文字列データには明確なエンコーディングが必要です。

HtmlEncodeメソッドの一般的な使用方法は、最終的には生のHTMLとしてレンダリングすることです。使用しているフレームワークによっては、それを処理する方がいいかもしれません。 ASP.Net MVCを使用している場合は、通常の@Model.Textですべての必要なエンコーディングが提供されます。

エンコーディングを指定する方法の1つとして、HtmlStringクラスを使用して、 "文字列値はそのままHTMLで安全にレンダリングできる生のHTMLを表します"と宣言することができます。値の変数/プロパティにHtmlEncodeの出力を格納することをお勧めします。誰もが値が消されており、直接描画されるべきであることを知っています。

関連する問題