テキストデータとHTML断片を区別する
2008年11月4日(火曜日)
テキストデータとHTML断片を区別する
公開: 2025年1月20日2時45分頃
「出力処理のホワイトリスト (rryu.sakura.ne.jp)」。
以前に上記の方法と同じようなものを検討したことがある。エスケープ漏れが発生するのは、同じ変数の中味が処理の段階によって未エスケープからエスケープ済みに変わったり、未エスケープとエスケープ済みの変数が何の区別もなく混在しているからだという話をどこかで読んだためだ。
「安全なテンプレートシステムはあるのか」ですかね。型が同じなのが良くないのではないかという話であって、変数の名前で区別する話ではありませんが。
……ところで余談ですが、新しいhatomaru.dllでも「全部DOMでつくり、InnerXml/OuterXmlには書き込まない」というポリシーは健在で、XSSに対する特別な配慮はほとんどしていません。それは良いのですが、実は「全部DOM」方式にも弱点があることが判明しています。
C#でこんなコードを書くと……。
XmlDocument result = new XmlDocument();
XmlCDataSection CDATA = result.CreateCDataSection("<![CDATA[CDATAのサンプル]]>");
これは問題なく動作しますが、このCDATAのOuterXmlを参照したり、ドキュメントをSaveしようとすると例外が発生します。
System.ArgumentException: XML CDATA ブロック内部に ']]>' を含めることはできません。
DOM方式なら何が来ても大丈夫、というわけではないのですね。
興味深いのは、ノードを生成することはできていて、出力しようとしたときにはじめて例外になるという点。内部的には ']]>' を含むXmlCDataSectionのノードがちゃんと生成されていて、出力するときにはじめてエスケープ処理を行おうとしていることが分かります。
※で、CDATA区間の中の ']]>' をエスケープして表現する方法が存在しないために例外になるわけですね。問題の部分をCDATA区間の外に出すか、あるいはCDATA区間を二つに分割すれば表現できますが、ノードの数が変わってしまいますし……。
※そもそも、CDATA区間は基本的に「エスケープして書くのが面倒」という時に使うので、DOMでCDATAを生成する意味はあまりありません。script要素に中身を書こうとしなければOK。
- 「テキストデータとHTML断片を区別する」へのコメント (1件)
- 前(古い): セキュアなPHPアプリケーションを作成するための7つの習慣
- 次(新しい): 何かが足りない気がする