カラクリサイクル

『輝かしい青春』なんて無かった人の雑記

express.jsとcoffeecup.jsを使うときは、@の前にhを使え。さもなきゃXSSる

概要: coffeecup.jsはデフォルトでHTMLエスケープしない


自戒を込めてメモ。

僕は、最近、

俺の考えた最強の掲示板システム(てってれー)

なるものをこそっと作ってたのですが、今日の今日まで、 そのシステムにXSS脆弱性をモロに埋め込んでました。

具体的にどういうことかというと、僕の作ってる掲示板システムは、

  • Express.js 3
  • coffeecup.js
  • その他色々

という感じの構成で作ってたのですが、テンプレートエンジンのcoffeecup.jsが、 デフォルトでは全自動HTMLエスケープをしない、 ということに気がついていませんでした。

まあ今となってはおいおいって感じですが、よくよく考えてみれば、 Text::MicroTemplateとか、あるいはText::Xslateみたいに、 全自動エスケープを搭載している方が少数派っぽく、 普通のテンプレエンジンはエスケープは任意で、って感じですよね。

で、もしこれに気がつかないままだったとすると、たぶん、 はまちちゃんあたりにイタズラされて、

らめぇぇぇぇスクリプト埋め込まれちゃうのおおおぉぉぉおぉぉ

という感じのコトを叫び、ひろみちゅ先生あたりからボロックソにののしられ、 最後の総仕上げにデッカいマーラネ申から実装面の問題を淡々と指摘される、 という恐怖のセキュリティみそ汁を味わうコトとなっていたような気がします。 ガクブル。あ、上記にには若干誇張が含まれています。

で、coffeecup.jsでのエスケープ問題の解決方法としては、

  1. @varsみたいな変数参照をh @varsという感じでエスケープする
  2. TemplateのCompile optionsでautoescape: trueを指定する

という感じの二通りになります。ちなみに僕は後者を選びました。

ちなみに後者のautoescape: trueを指定すると、 基本すべてのテキスト出力がエスケープされるので、 生のhtmlなどを書きたい場合は、

p -> text '<em>hoge</em>'

という感じでかき、またエスケープが必要な編集をプレーンテキストで表示したい場合、

p -> text h '<nyarla>'

という感じで書くとOKです。ちなみになんでtext h '<nyarla>'になってるか、 というと、h '<nyarla>'だけだと、二重エスケープされちゃうからです。 まあ詳しく試してみると分かります。


ま、そんな感じで、今日は自分の作ってるモノの脆弱性に気がつけたのでよかったです。

さすがに僕もはまちちゃんの餌食にはなりたくないので、 今後はテンプレートエンジンの仕様とかには、気を使いたいと思います。

というわけで、今日のメモおわり。まる。