FreeTextBox(2)

FreeTextBox自体には無害化機能がないことをid:machi_pon:20060614に書きました。
FreeTextBoxを安全に使うためには、入力データから許可しないタグと属性のそぎ落としが必要と言うことで、その為に使用するHtmlParserを書いてみました。


こんな感じのクラス達です(・∀・)

public class HtmlAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public char Delimit { get; set; }
    public HtmlAttribute();
}
public class HtmlTag
{
    public string Name { get; set; }
    public bool IsSingle { get; set; }
    public IList<HtmlAttribute> Attributes { get; set; }
    public HtmlTag();
    public HtmlAttribute GetAttribute(string attrname);
    public string BuildTag();
}
public class ParseResult
{
    public string Literal { get; set; }
    public HtmlTag Tag { get; set; }
    public ParseResult(string data);
    public ParseResult(HtmlTag tag);
}
public class HtmlParser
{
    public string Source { get; set; }
    public HtmlParser();
    public ParseResult Parse();
}

HtmlParserにソースのHTMLを渡して、Parse()を呼び出す度にタグ部/非タグ部をParseResultとして返していきます。
ParseResultは、結果がタグ部の場合はTagプロパティにHtmlTagが格納されます。
HtmlTagは、タグの属性一覧をAttributesプロパティとして保持しています。


Parse()メソッド内の実装は単純に、文字列のフェッチや空白スキップしながら、タグ、属性、属性の値をパースする処理をベタに書いています。


で、FreeTextBoxの入力をこのHtmlParserに渡して、HtmlTagが返ってきた場合にはそのNameとHtmlAttributeコレクションのチェックを行い、許可されてないタグと属性については削除して、HTMLを再構築していくと無害化されたHTMLを取得できるようになります。


…っというものを作ったんですが、こういう正規表現を使えばタグの抽出は簡単にできるそうで…orz

Regex regex = new Regex( "<[^<>]+>?", RegexOptions.Compiled|RegexOptions.Multiline|RegexOptions.IgnoreCase );

正規表現は得意じゃないのです…(´・ω・`)


正規表現も勉強しないとですね。

詳説 正規表現 第2版

詳説 正規表現 第2版


ちなみに、無害化ってこれだけで良いんでしょうかね?
"javascript:"みたいな文字列も取り除いた方が良いとして、その他にもした方が良いこととしては何があるんでしょうか。

FreeTextBoxの親戚みたいなのもいくつかありますが。

  • FCKeditor

http://www.fckeditor.net/

  • TinyMCE

http://tinymce.moxiecode.com/

  • Kupu

http://kupu.oscom.org/


TinyMCEは無害化機能を持っているらしいので、その辺も調べてみましょうか。


ところで、HTMLパーサって無害化以外にも、Templateエンジンとかダウンローダ用のタグ抽出とか、意外と使い道があるかもしれないですね(´ω`)