(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 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について」に続く。

Perl | セキュリティ
Sep 22, 2010 18:25



Comments

View Comments (0)

Post a comment