« テストケースの実行にあわせて Apache を起動・終了する方法 | Main | String::Filter っていうモジュール書いた - 続: (Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について »

September 22, 2010

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

TrackBack

TrackBack URL for this entry:
http://bb.lekumo.jp/t/trackback/404050/25099335

Listed below are links to weblogs that reference (Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について:

» 構造化テキストの間違ったエスケープ手法について from 404 Blog Not Found
昨晩のtwitter XSS祭りは、ふだんもtwitter.comは使わない私には遠くの祭り囃子だったのですが、せっかくの自戒の機会なので。 Kazuho@Cybozu Labs: (Twitter の XSS 脆弱性に関連して) 構造化テキストの正しいエスケープ手法について正しいアプローチは、全てのルールを同....... [Read More]

Comments

Post a comment