1

(潜在的に敵対的な)ユーザー入力フィールドを処理するためのコントローラーメソッドには、次のコードがあります。

string tmptext = comment.Replace(System.Environment.NewLine, "{break was here}"); //marks line breaks for later re-insertion
tmptext = Encoder.HtmlEncode(tmptext);
//other sanitizing goes in here 
tmptext = tmptext.Replace("{break was here}", "<br />");

var regex = new Regex("(<br /><br />)\\1+");
tmptext = regex.Replace(tmptext, "$1");

私の目標は、典型的な悪意のない使用のために改行を保持し、安全な html エンコードされた文字列でユーザー入力を表示することです。ユーザー入力を取得し、改行文字を解析して、改行に区切り記号を配置します。HTML エンコーディングを実行し、改行を再挿入します。(これを変更して、段落を br ではなく p タグとして再挿入する予定ですが、今のところ br を使用しています)

実際に実際の html ブレークを挿入すると、微妙な脆弱性に直面する可能性があります: Enter キーです。regex.replace コードは、エンター キーの上に立ってページをがらくたで埋めている悪意のあるユーザーを排除するためにあります。

これはただの白の大きながらくたフラッドの修正ですが、1 文字、2 つの改行、1 つの文字、2 つの改行をページ全体に入力するなど、悪用される可能性があります。

私の質問は、これが不正であると判断し、検証に失敗する方法です。それを行うための単純な手続き型の方法がなく、代わりにヒューリスティック手法またはベイジアンフィルターが必要になるのではないかと心配しています。うまくいけば、誰かがより簡単でより良い方法を持っています。

編集: おそらく、問題の説明が明確ではありませんでした。正規表現は、複数の改行が連続して表示され、それらを 1 つまたは 2 つに変換することを処理します。その問題は解決しました。本当の問題は、正当なテキストとがらくたフラッドを次のように区別することです。

a

a

a

...これらの 1000 を想像してみてください...

a

a

a

a

4

5 に答える 5

0

正規表現を使って「賢い」何かを試してみたいと思われるかもしれませんが、IMOの最も簡単なアプローチは、文字列の文字をループしてStringBuilderにコピーし、フィルタリングすることです。

char.IsWhiteSpace()テストに失敗したものはコピーされません。(これらのいずれかが改行である場合は、<br/>を挿入し、空白以外の文字をヒットするまで<br/>を追加しないようにします)。

編集

ユーザーが古いがらくたを入力するのを止めたい場合は、今すぐあきらめてください。ユーザーが本当に望んでいるのであれば、ユーザーが1分以内に回避策を見つけることができないようなフィルタリングの方法を見つけることは決してありません。

入力の改行数または文字の総数に制限を設ける方がはるかに良いでしょう。

「悪い入力」をサニタイズするために何か賢いことをするのにどれだけの努力が必要かを考えてから、これが起こる可能性がどれほどあるかを考えてください。おそらく意味がありません。おそらく、本当に必要なすべてのサニタイズは、データが合法であることを確認することです(システムが処理するには大きすぎない、すべての危険な文字が削除またはエスケープされているなど)。(これが、適切な基準に基づいて投稿をフィルタリングできる人間のモデレーターがフォーラムにいる理由です)。

于 2012-04-12T13:26:54.817 に答える
0

これは、これを処理する最も効率的な方法でも、最もスマートな方法でもありません (免責事項)
が、テキストが大きすぎない場合は、それほど重要ではなく、よりスマートなアルゴリズムに欠けています (注: 次のようなものを検出するのは難しいchar\nchar\nchar\n...ですが、線長に制限を設定します)

白い文字だけSplitを使用することもできます (\n 以外の考えられるものをすべて追加します)。次にJoin、スペースを 1 つだけ使用してから (行を取得するために) 分割し、 で\n結合し<br />ます。line.Length > 2行に参加している間、たとえば何か をテストできます。

これを高速化するには、IndexOf などを使用して、より効率的なアルゴリズム、char ごとに char を反復処理できます。

繰り返しますが、これを処理する最も効率的または完璧な方法ではありませんが、何か高速なものが得られます。

EDIT:「同じ行」をフィルタリングするには-たとえば、 「同じ行」を連続してフィルタリングする必要がある(NuGet Ix-experimentalを参照) DistinctUntilChangedからのものを使用できます+それらの行テストを追加できます。Ix - Interactive extensions

于 2012-04-12T13:43:26.167 に答える
0

slashdot.org のコメント フィルターに触発されたランダムな提案: System.IO.Compression.DeflateStream を使用してユーザー入力を圧縮し、元のフィルターと比較して小さすぎる場合 (役に立つものを見つけるために実験を行う必要があります)カットオフ)それを拒否します。

于 2012-04-12T14:14:27.933 に答える
0

文字列をHttpUtility.HtmlEncode取得してから、改行文字を<br/>.

HttpUtility.HtmlEncode(subject).Replace("\r\n", "<br/>").Replace("\r", "<br/>").Replace("\n", "<br/>");

また、データベースに保存するときではなく、ユーザーに出力するときにこのロジックを実行する必要があります。データベースで行う唯一の検証は、適切にエスケープされていることを確認することです (通常のビジネス ルールを除く)。

編集:ただし、実際の問題を解決するには、正規表現を使用して、複数の改行を事前に単一の改行に置き換えることができます。

subject = Regex.Replace(@"(\r\n|\r|\n)+", @"\n", RegexOptions.Singleline);

が必要かどうかわかりませんRegexOptions.Singleline

于 2012-04-12T13:34:53.320 に答える
0

改行をフィルタリングされたテキストに置き換えて正規表現を使用しようとするのではなく、<br />タグを挿入する前にデータをサニタイズしてみませんか? 最初に入力をサニタイズすることを忘れないでくださいHttpUtility.HtmlEncode

続けて複数の短い行を処理しようとして、これが私の最善の試みです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class Program {
  static void Main() {
    // Arbirary cutoff used to join short strings.
    const int Cutoff = 6;

    string input =
      "\r\n\r\n\n\r\r\r\n\nthisisatest\r\nstring\r\nwith\nsome\r\n" + 
      "unsanatized\r\nbreaks\r\nand\ra\nsh\nor\nt\r\n\na\na\na\na" +
      "\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na";
    input = (input ?? String.Empty).Trim(); // Don't forget to HtmlEncode it.
    StringBuilder temp = new StringBuilder();
    List<string> result = new List<string>();
    var items = input.Split(
                        new[] { '\r', '\n' },
                        StringSplitOptions.RemoveEmptyEntries)
                     .Select(i => new { i.Length, Value = i });

    foreach (var item in items) {
      if (item.Length > Cutoff) {
        if (temp.Length > 0) {
          result.Add(temp.ToString());
          temp.Clear();
        }

        result.Add(item.Value);
        continue;
      }

      if (temp.Length > 0) { temp.Append(" "); }
      temp.Append(item.Value);
    }

    if (temp.Length > 0) {
      result.Add(temp.ToString());
    }

    Console.WriteLine(String.Join("<br />", result));
  }
}

次の出力が生成されます。

thisisatest<br />string with some<br />unsanatized<br />breaks and a sh or t a a
 a a a a a a a a a a a a a a a a a a a

あなたはすでにこの解決策を思いついたと思いますが、残念ながら、あなたが求めていることはあまり簡単ではありません.

興味のある方のために、これが私の最初の試みです:

using System;
using System.Text.RegularExpressions;

class Program {
  static void Main() {
    string input = "\r\n\r\n\n\r\r\r\n\nthisisatest\r\nstring\r\nwith\nsome" +
                   "\r\nunsanatized\r\nbreaks\r\n\r\n";
    input = (input ?? String.Empty).Trim().Replace("\r", String.Empty);
    string output = Regex.Replace(
                      input,
                      "\\\n+",
                      "<br />",
                      RegexOptions.Multiline);
    Console.WriteLine(output);
  }
}

次の出力を生成します。

thisisatest<br />string<br />with<br />some<br />unsanatized<br />breaks
于 2012-04-12T13:35:36.363 に答える