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 );
正規表現も勉強しないとですね。
- 作者: Jeffrey E.F. Friedl,田和勝
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2003/05/26
- メディア: 単行本
- 購入: 4人 クリック: 241回
- この商品を含むブログ (110件) を見る
ちなみに、無害化ってこれだけで良いんでしょうかね?
"javascript:"みたいな文字列も取り除いた方が良いとして、その他にもした方が良いこととしては何があるんでしょうか。
FreeTextBoxの親戚みたいなのもいくつかありますが。
- FCKeditor
- TinyMCE
- Kupu
TinyMCEは無害化機能を持っているらしいので、その辺も調べてみましょうか。
ところで、HTMLパーサって無害化以外にも、Templateエンジンとかダウンローダ用のタグ抽出とか、意外と使い道があるかもしれないですね(´ω`)