モドキの効用...たとえば XPathモドキ?
2007.05.01
これは遊びで書いているプログラムで出た問題です。
要するにブログのコメントなんかに対するサニタイザです。この時に、「存在していいタグ」を指定して、許可されたタグだけはそのままで、それ以外のタグはエスケープする、という処理がありますよね。まあ、一般に「許されるタグ」は単純に属性なしでそれなりの動作をするタグがほとんどです。
とはいえ、このサニタイザ仕様に対して、「属性を許可したり、特定の属性を排除したり...」という指定を与えるのはどうすればいいのでしょうか? タグ名だけならば、当然タグ名の列挙で充分なのですが、たとえば、
a タグに対して、href 属性と name 属性、target 属性はあっていい。しかし、onclick 属性など内部に JavaScript の書ける属性は禁止だし、href 属性でも
<a href="javascript:window.localtion.href=.....">リンクだよん</a>
のように、javascript URI を指定している場合は禁止にしたい...
というような、結構ゼータクなことをしたい、ということを考えて見ましょう。この指定をデータとしてどう記述するのでしょう???
これ、やはり「似た公的規格」を準用するのがいいのでは...と思いませんか。というわけで、私は XPath 風にこれを書くのがいいんじゃないか..と思って、その方向での実装をしていきました。たとえば、上記の例だと、とりあえずこんな感じでしょうか。
禁止指定: a[@href="javascript:*"]
許可指定: a[@href] a[@target] a[@name]
擬似コードで書いた動作はこんなところです(単純化のために、複数の属性がある場合などは略です)。
function needSanitize( tag ) {
if( tag.match( 禁止指定 ) { return 禁止; }
if( tag.match( 許可指定 ) { return 許可; }
return 禁止;
}
で、「禁止・許可の指定のために XPath モドキで指定する」ということですから、たとえば本当は JavaScript URI のチェックは、XPath 関数を使って、
starts-with(a[@href], 'javascript:')
とでも書くべきではあるのでしょうが、簡潔さで以上のような XPath 外のワイルドカード指定みたいなことにしました。「すべての属性は不可だが、属性のない b タグは許可」という指定ならば、
禁止指定: b[@*]
許可指定: b
みたいに実現できればいいように思います。これは XPath にちゃんとある書き方ですね。とはいえ、
禁止指定: b[@on*]
許可指定: b b[@*]
で onclick などの JavaScript が書ける属性のみ不可、とする場合には、属性名に対する先頭一致の感覚で書いている on* は、XPath の規格外になります(というか、正確には「on*」という名前の属性と一致するようですから、規格「内」なんですけどね)。
まあ、こんな風に「別に XPath じゃないけども、見た目を XPath に合わせてやる」というのも、実装仕様としては、もう大丈夫ではないか...とも思います。ちょっと調べてみると、ネット上で配布しているものでは「Webサイトの更新時刻取得エージェント」である「五月雨」が、更新判定から除外すべき部分を XPath 風に指定する、というのがあったりします。今回のものなんか、Well-formed な XMLであること自体がまったく期待できないコメントなので、ちゃんとした XPath ライブラリにお願いすることがそもそも無理だったのですが、そういう風な「見かけだけ」なXPath モドキというものも、「コミュニケーションという問題」で有用なのかもしれません。たとえば、もうすでに、
//web-app/servlet/servlet-name
くらいまでは一般に多分許容範囲ではないでしょうか。
投稿者 : 杉浦 こずえ | 投稿日時 : 2007.05.01 15:49





