パスワードを忘れた? アカウント作成
677338 journal

airheadの日記: !: 予備エントリ

日記 by airhead

現在test.slashdot.jpで試験運用されているSlashcode 2.5の日記RSSは、問題を引き起こす可能性があるように思われます。この種の問題は古くから指摘されており、釈迦に説法になるかもしれませんが以下順を追って説明します。(2005/07/11 20:40)

----

現状

次のような内容の日記エントリ(a)があるとする。一行目には、読者がHTMLタグを目視できるように書かれている。

「<a href="http://example.com">example.com example.comへのリンクになります。 ...(a)

このときSlashcode 2.5から送られるHTMLソースの当該部分は、ユーザーの記述にもよるが概ね次の(b)のようになっているだろう。また現在運用中のSlashcode (2.2?)に関して、投稿・プレビューの段階で文字実体参照「&lt;」が「<」に展開されるのを避けるための、「&LT;」と大文字で記述する手法(b')が知られている。

「&lt;a href="http://example.com"&gt;example.com&lt;/a&gt;」というHTMLを書くと<br>
<a href="http://example.com">example.com</a>へのリンクになります。
...(b)

「&LT;a href="http://example.com"&GT;example.com&LT;/a&GT;」というHTMLを書くと<br>
<a href="http://example.com">example.com</a>へのリンクになります。
...(b')

Slashcode 2.5は日記RSSの生成に際して、HTMLソース断片に対してさらなる文字実体参照への置換を行ったうえでdescription要素内に含めているが、現状で置換されているのは「<」→「&lt;」のみである。上記(b), (b')に相当するdescription要素の内容は、次の(c), (c')のようになる。

「&lt;a href="http://example.com"&gt;example.com&lt;/a&gt;」というHTMLを書くと&lt;br>
&lt;a href="http://example.com">example.com&lt;/a>へのリンクになります。
...(c)

「&LT;a href="http://example.com"&GT;example.com&LT;/a&GT;」というHTMLを書くと&lt;br>
&lt;a href="http://example.com">example.com&lt;/a>へのリンクになります。
...(c')

問題

これは受け取ったRSSリーダ上で問題を引き起こす可能性がある。

問題(1) RSSリーダはdescription要素内(c)の文字実体参照から、(d)のような内容が含められていると解釈する。そしてそれをRSSリーダがHTMLとして解釈する場合、次の(e)のように1行目の鍵括弧内もHTMLとしてレンダリングしてしまう。

「<a href="http://example.com">example.com</a>」というHTMLを書くと<br>
<a href="http://example.com">example.com</a>へのリンクになります。
...(d)

example.com」というHTMLを書くと
example.comへのリンクになります。 ...(e)

この例ではa要素を用いておりレンダリング内容が投稿者の意図(a)と異なるだけにとどまっているが、ウェブブラウザ向けのコンテントには存在するSlashcodeの投稿タグ規制がRSSリーダ向けのコンテントには存在せず、投稿者からRSS購読者への攻撃に使われる可能性がある。どちらかといえばRSSリーダ側で対処すべき問題かもしれないが、実際問題としてHTMLと解釈しレンダリングするRSSリーダは存在するため、CMS側での対処も望まれる。参考: Embedded Markup Considered Harmful

問題(2) RSSリーダはRSSをXML1.0構文に沿って解釈するが、(c')の大文字で書かれた文字実体参照「&LT;」「&GT;」は構文エラーとなり、パーサを通らない。手法(b')で書かれた日記エントリは数多く存在する。参考:Motohikoさんの指摘

とりあえずの対処

問題(1)について考えられるとりあえずの対処法は、RSS生成時にdescription要素内をCDATAセクションにして(b)ないし(b')を置換なしでそのまま埋め込むことだ。

あるいは、置換を「<」→「&lt;」のみではなく、「&」→「&amp;」、「<」→「&lt;」、「>」→「&gt;」の順に行うことが考えられる。(b)に含まれている「&lt;」は「&amp;lt;」に置換される。「&」の置換を先にするのは、RSSリーダにHTMLとして解釈させたいタグまで「&amp;lt; ~ &amp;gt;」と置換されるのを避けるためである。が、やはり上記CDATAセクションの利用による対処のほうが容易だろう。

上記いずれかの対処法を取ることで問題(2)も回避できるが、Motohikoさんが指摘するように既存の日記データをインポートする際の置換が対処として妥当だろう。

さらなる対処

RSSのdescription要素は、リソースの簡潔な要約となるよう意図されている。(b)からタグを取り除き500bytes程度にしたものをdescription要素に、(b)全文はContentモジュールのcontent:encoded要素に含めるのが適当だろう。以上の対処法をまとめると、次の(f)のようになる。参考:RSS -- サイト情報の要約と公開(Web KANZAKI)

<rdf:RDF
(中略 現状のxmlnsに以下のxmlns:contentを追加)
xmlns:content="http://purl.org/rss/1.0/modules/content/"
>
(中略)
<description><![CDATA[「&lt;a href="http://example.com"&gt;example.com&lt;/a&gt;」というHTMLを書くと
example.comへのリンクになります。]]></description>
<content:encoded><![CDATA[「&lt;a href="http://example.com"&gt;example.com&lt;/a&gt;」というHTMLを書くと<br>
<a href="http://example.com">example.com</a>へのリンクになります。]]></content:encoded>
...(f)

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」

読み込み中...