(Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について昨日の Twitter の XSS 騒ぎは、まだ皆さんの記憶に新しいことと思います。いい機会なので、ツイートのような構造化テキストのエスケープ手法について触れておきたいと思います。
Twitter のメッセージは、単なる平文(プレインテキスト)ではなく、「@英数字」のような他のユーザーへの言及と「http://〜」のような URL を自動的にハイパーリンク化する構造化テキストです。
このような複数のルールをもつ構造化テキストを HTML 化する際には、どのようなコードを書けばいいのでしょう? まず「@〜」をリンク化してから、URL をリンク化すればいいのでしょうか? それだと、@〜 のをリンク化した A HREF タグの中の URL がさらにリンク化されていまいますね。
では、URL をリンク化してから @〜 をリンク化すればいいのでしょうか? それだと、@ を含む URL があった場合に、やはり HTML が壊れてしまいます。
正しいアプローチは、全てのルールを同時に適用することです。
Perl で書くなら、以下のように、「@〜」と URL を検出するパターンを単一の正規表現にまとめてトークナイズ (split) し、切り出されたトークンがどのタイプかを判定しながら処理していきます。
my $html = ''; for my $token (split m{(http://[0-9A-Za-z_\.\%\?\#\@/]+|\@[0-9A-Za-z]+)}, $tweet) { if ($token =~ m{^http://}) { $html .= '<a href="' . encode_entities($token) . '">' . encode_entities($token) . '</a>'; } elsif ($token =~ m{^\@(.*)$}) { my $user = $1; $html .= '<a href="http://twitter.com/' . encode_entities($user) . '">' . encode_entities($token) . '</a>'; } else { $html .= encode_entities($token); } }でもルールが複雑になってくると面倒なので... 続きはあとで書く「String::Filter っていうモジュール書いた - 続: (Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について」に続く。
View Comments (0)
Post a comment