テンプレートシステムはデフォルトでエスケープするべきじゃなかろうか?

mixiに機能要望の投票とトラッキングがついたらしいので、個人ごとにタイムゾーン設定できるようにってのに投票しました。
# 現時点で評価は 良い94/悪い4 なんだけど、いつになったら検討されるのかさっぱり謎です。

で、他にどんな面白い要望があるんだろうかとブラウズしたりして、ふと実装済のところを見てみると、XSS脆弱性の修正が並んでる・・・
しかも、「mixi機能要望におけるXSSの問題を根本的に修正してほしい」なんてのを筆頭に、最近リリースされてる機能にも平気でXSS脆弱性があった模様。

いまどきリリースされるwebアプリでも、XSS脆弱性はゴロゴロしてるのね。
まあ、そこらのサンプルコードや入門書にXSS脆弱性やSQLインジェクションがゴロゴロしてるのは知ってましたが、mixiでリリースされてるアプリケーションでも未だにゴロゴロしてるとは、ちょっとびっくりです。

mixiのシステムはおいといて、ふと思ったのが「テンプレートシステムはデフォルトでエスケープするべきじゃなかろうか?」ってこと。

DBなどに入力値をそのまま持っておく設計(極めてフツーだけど)のwebアプリケーションだと、たとえばsmartyなら、HTMLを保存しているもの以外の全ての変数表示項目で{$hogehoge|escape}として、エスケープする必要があります。
「ちゃんとエスケープしろよ」といっちゃえばそれまでなのですが、テンプレートってのはwebデザイナーさんもいじることがあるわけで、webデザイナーさんがescapeを忘れちゃったり間違えて取っちゃったりする可能性ってのは十分あるわけです。

このあたりの危うさを考慮すると、テンプレートシステムではデフォルトでエスケープするほうが安全だし、コードの量も減るでしょうね。

関連記事

6個のコメント

  1. 2006 年 8 月 8 日 2:07 AM に投稿 | パーマリンク

    ふと思ったのが「テンプレートシステムはデフォルトでエスケープするべきじゃなかろうか?」ってこと。

    これ、激しく賛成ですね。
    でも現実としてそうなってないし、やっぱりWebアプリ側でちゃんとしてあげるしかない気がします。
    でも、inputとoutputの両方でデータのチェックして、正当性をWebアプリが保障するのは、「PHP」とか言っている時点で相当メンドウな作業ですね(開発・メンテナンス全般で)。
    世の中、そうそう上手くできてませんです。

  2. 2006 年 8 月 8 日 2:53 AM に投稿 | パーマリンク

    ホントにそうですね。
    自分でも |escape 100%付け忘れあります。

    フレームワークでいうと、Ethnaはエスケープ済みがデフォルトでした。(たしか)

    Smartyだと、フィルターで全部エスケープされるようにしておいて、したくないのだけ逆に {$hogehoge|unescape}とか作っておけばいいんですかね。

  3. 2006 年 8 月 8 日 5:24 AM に投稿 | パーマリンク

    MapleのSmartyViewも3.1からデフォルトエスケープにしました。

    Smartyは「$default_modifiers」というのを使って、デフォルトエスケープにすることはできます。で、エスケープしてほしくない時は{$hoge|smarty:nodefaults}とすることになります。

    ただし、{foreach from=$from item=item}の$fromをエスケープしようとしてエラーがでたりと少々わずらわしいというのはあります。({foreach from=$from|smarty:nodefaults item=item}としないといけないです)

  4. 2006 年 8 月 8 日 10:11 AM に投稿 | パーマリンク

    komagataさん、kunitさん、最新情報をどうもです
    さすが国産フレームワークは痒いところに手が届く感じですね
    # EthnaもMapleも一度じっくり使ってみたいんですが、なかなかじっくり使う時間が取れなくて・・・

    smartyのdefault_modifiersはマニュアル
    http://smarty.php.net/manual/en/variable.default.modifiers.php
    にも記述がありました。まったく見逃してました!反省

  5. 2006 年 8 月 10 日 6:30 PM に投稿 | パーマリンク

    こんにちは。デフォルトでエスケープさせる件ですが、難しいところですね。

    どうしても生の値をテンプレートに埋めたい場面は出てくるでしょうし、その部分はコード側でエスケープする必要がありますよね。このようにエスケープをする場所がテンプレートとコード中に散在するとXSSの有無の見通しが悪くなると思うんですよ。

    出力段階でエスケープさせるのを「出口方式」とするなら、僕は「入口方式」の方を採用してます(URL参照)。「入口と出口の両方で」と簡単にいけばこんなに悩まなくても済むのに……。

    http://kaede.to/~canada/doc/yoyiyayiye

    ここではGETやPOSTしか触れてませんが、ENV, Session, Cookie周りやDBの戻り値などにも気をつける必要がありますよね……。

  6. 2006 年 8 月 10 日 11:34 PM に投稿 | パーマリンク

    かなださんこんちわです。
    そうですよね、散在はよくないですね。
    プロジェクトレベルできっちりとXSS対策の方針固めとかないと、あとあと悲惨なことになるのはよくある話になっちゃいますね。