ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

mixiのみょうなXSS対策

http://www.msng.info/archives/2009/06/caracter_reference_on_mixi_diary.php
と言うのを見て、確認してみた。
mixiでは、コメントや日記の本文を確認する画面が出てくるが、実際に書き込みするために、hiddenフィールドでデータのやり取りをやっている。これはサーバの負荷等を考えてのことだろうと思われる。

ということで、コメントや日記の本文に「&"><&amp;」を入れてみた。
そうすると、確認画面では以下のようなレスポンスが得られる。

<p>&"&gt;&lt;&amp;</p>
:
<input type="hidden" name="comment_body" value="&&quot;><&amp;" />

表示部分では、「&」->「&」、「"」->「"」、「<」->「&lt;」、「>」->「&gt;」と変換しているのに対し、hiddenの値は「&」->「&」、「"」->「&quot;」、「<」->「<」、「>」->「>」としか変換していない。ところが、ブラウザが「&amp;」を「&」に変換してしまうため、「&amp;」->「&」としてアプリに渡されてしまう。
したがって日記を表示してみると以下のようなレスポンスとなる

&"&gt;&lt;&

今度は、「&」->「&」、「"」->「"」、「<」->「&lt;」、「>」->「&gt;」となる。しかし、奇妙なことに「&amp;」->「&」というおかしな変換を行っている。
この結果「&amp;」とコメントに入力しようとすると、「&amp;amp;amp;」とするしかない。
どうやら、mixiでは、必要最低限の変換(hiddenに格納されたデータは「"」->「&quot;」、データ表示時は「<」->「&lt;」、「>」->「&gt;」)しか行っていないようだ。しかし、データ保存時には、「&amp:」をなぜか「&」に変換して保存すると言うことを行っているようである。一方、ブラウザが「&amp;」を「&」と認識してしまうため、このようなことがおこる。hiddenの表示でも「&」->「&amp;」と言う変換をしなくてはいけない。
これは、アプリケーションの作りから言って、データが意図しない変換を行うため非常にまずい。
しかも、エスケープ関数を2種類用意し、それを場合場合によって選んで使わなければならないので、間違いを起こしやすくなるので、勧められたものではないと思う。
どうやら、場当たり的な対策が見えるんだけど、どうなんだろう?
(追記)
どうも、「&amp;」と「&」を内部では同一のものと考えて処理しているような気がするなぁ。「<」と「&lt;」、「>」と「&gt;」、「"」と「&quot;」は区別しているようだけど・・・

(追記2)
原因はmixi「&」を「&amp;」に変換しないからだ。ブラウザが「&amp;」を「&」に変換して送信してしまうため、これを受け取ったアプリは「&」と認識してしまう。これはバグだなぁ。