mixiのみょうなXSS対策
http://www.msng.info/archives/2009/06/caracter_reference_on_mixi_diary.php
と言うのを見て、確認してみた。
mixiでは、コメントや日記の本文を確認する画面が出てくるが、実際に書き込みするために、hiddenフィールドでデータのやり取りをやっている。これはサーバの負荷等を考えてのことだろうと思われる。
ということで、コメントや日記の本文に「&"><&」を入れてみた。
そうすると、確認画面では以下のようなレスポンスが得られる。
<p>&"><&</p> : <input type="hidden" name="comment_body" value="&"><&" />
表示部分では、「&」->「&」、「"」->「"」、「<」->「<」、「>」->「>」と変換しているのに対し、hiddenの値は「&」->「&」、「"」->「"」、「<」->「<」、「>」->「>」としか変換していない。ところが、ブラウザが「&」を「&」に変換してしまうため、「&」->「&」としてアプリに渡されてしまう。
したがって日記を表示してみると以下のようなレスポンスとなる
&"><&
今度は、「&」->「&」、「"」->「"」、「<」->「<」、「>」->「>」となる。しかし、奇妙なことに「&」->「&」というおかしな変換を行っている。
この結果「&」とコメントに入力しようとすると、「&amp;amp;」とするしかない。
どうやら、mixiでは、必要最低限の変換(hiddenに格納されたデータは「"」->「"」、データ表示時は「<」->「<」、「>」->「>」)しか行っていないようだ。しかし、データ保存時には、「&:」をなぜか「&」に変換して保存すると言うことを行っているようである。一方、ブラウザが「&」を「&」と認識してしまうため、このようなことがおこる。hiddenの表示でも「&」->「&」と言う変換をしなくてはいけない。
これは、アプリケーションの作りから言って、データが意図しない変換を行うため非常にまずい。
しかも、エスケープ関数を2種類用意し、それを場合場合によって選んで使わなければならないので、間違いを起こしやすくなるので、勧められたものではないと思う。
どうやら、場当たり的な対策が見えるんだけど、どうなんだろう?
(追記)
どうも、「&」と「&」を内部では同一のものと考えて処理しているような気がするなぁ。「<」と「<」、「>」と「>」、「"」と「"」は区別しているようだけど・・・
(追記2)
原因はmixiが「&」を「&」に変換しないからだ。ブラウザが「&」を「&」に変換して送信してしまうため、これを受け取ったアプリは「&」と認識してしまう。これはバグだなぁ。