水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > 2011年のえび日記 > 2011年9月 > 2011年9月6日(火曜日)

2011年9月6日(火曜日)

<i>区切りという斬新なデータ形式

公開: 2011年9月10日11時30分頃

徳丸さんの書籍の脆弱性シリーズ、「PHPのイタい入門書を読んでAjaxのXSSについて検討した(2)~evalインジェクション~ (d.hatena.ne.jp)」。脆弱性の話より、データ形式の話のインパクトが強いです。

本書ではJSONの説明も少し出てくるのですが、実際に使われている形式は、HTMLのi要素「<i>」を用いてデータを区切るというユニークな方法です。以下にデータの例を示します。

30<i>山田<i>ABC<i>234-5678<i>Bコース<i>5<i>2010-04-29<i>2010-04-30

前のエントリで、「out.split("<i>")」というスクリプトが出てきましたが、この形式をデコードする目的だったわけです。

<i>という文字列をデータの区切りにしているという。徳丸さんはi要素とされていますが、i要素としてのマークアップを意図しているようにも思えず、たまたまそういう文字列になっているだけのようにも見えます。

10年以上昔の掲示板のPerlスクリプトでは、データを「<>」で区切る形式がよく使われていました。その手のスクリプトでは、入力時に「<」や「&」「>」をそれぞれ「&lt;」「&amp;」「&gt;」に変換してしまい、後はずっとそのまま使うという手法がとられていました。そのため、入力時の処理が終わった後のデータに「<>」が含まれていることは絶対にありません。このようなケースで「<>」を区切りにすることには、一定の合理性があります。

※もっとも、入力時に「<」を変換してしまう手法には問題もあります。HTMLに出力するだけなら良いのですが、電子メールの本文に出力したり、JSON形式で出力したりする場合、いちいち「&lt;」などを元に戻す必要があって実に面倒です。文字数をカウントしたり、正規表現でマッチさせたりするのも面倒になります。最近はHTML以外の形式を扱うことが増えてきていることもあり、このような処理はあまり見られなくなっています。

しかし、このスクリプトでは入力値を全く変換していないわけですから、「<i>」で区切る理由が見いだせません。

そもそも、このデータはサーバ内部で保存するものではなく、APIがレスポンスとして返してくるデータです。JSからのアクセスを想定したAPIが返すデータは、JSON, JSONP, XML あたりにするのが定石です。定石であるが故に、JS側でそのようなデータを扱うライブラリも充実していますから、JS側の実装負担が少なくて済みます。よほどの理由がない限り、オリジナルのデータ形式を使うべきではないでしょう。

徳丸さんは以下のように続けられていますが、

データをカンマで区切るCSV形式を採用しなかった理由は、データ中にカンマが出てくる場合などがややこしいと著者が判断したからかもしれません。しかし、データを利用者が登録できるという前提では、「<i>」が入力される可能性はあります。この場合、データが1つずれるということが起こり、状況によっては脆弱性になります。本書の場合、その対処はなされていません。

これも問題です。データとして「<i>」を出力したい場合に、エスケープをどうするのか考えなくてはいけません。定石のデータ形式を採用すれば、こういった細かい仕様もしっかり決められていますし、ライブラリが勝手にエスケープしてくれることも多いです。

※とはいえ、IEがJSONをHTMLとみなしてしまうケースなどを考慮して、ライブラリの標準よりも広い範囲でエスケープ処理を行う場合もあります。半角英数以外の文字全てを\uXXXX形式でエスケープしてしまうとか。

まあ、そんなわけで、「<i>」で区切る形式を採用する積極的な理由は特にないでしょう。どうしてこんなオリジナリティ溢れるデータ形式を思いついたのかが謎ですが、行の区切りは<r>らしいです。ということで、元々「<>」を使っていて、2種類の区切り子を使い分ける必要が生じたので「<r>」をrowの区切り、「<i>」をitemの区切りとしたのではないか、という説を提唱してみます。

いずれにしても、今後「<r>」や「<i>」で区切る方法を採用する機会はないと言って良いと思いますので、はっきり言えばどうでもいい話ではあります。

データを「<i>」で区切る方法は読者も興味がないと思うので、これに関してはこの程度にとどめます。

徳丸さんのこの記述は秀逸で、思わず吹き出してしまいました。

関連する話題: プログラミング / PHP / JavaScript / 書籍の脆弱性

最近の日記

関わった本など