XSSを発見した。またはJSダブルクオートのススメ

もう修正・対策済みなので喋ってしまいますが、自社のサービスにXSS脆弱性を見つけてしまったのです。

サーバサイドは node.js で、テンプレートエンジンは jade(pugjs)。問題のコードを簡略化して書くと以下のようになります。

head
  script
    var hoge = {
       a: '#{param}',
       b: 'fuga'
    }; 

恐ろしい事に、このparam変数にはURLのクエリストリングの値が入るのです。はい、もう嫌な予感しかしないですね〜

jadeは < > % " をエスケープしますが、シングルクオートはエスケープせず出力されてしまいます。

ということは、以下のようなパラメータを渡すと ' がそのまま出力されてしまうため window.alert が実行されてしまうんじゃないですかねー。

http://localhost:3000/login?param=',x:window.alert('xss'),y:'

生成されるHTMLを整形すると…

<head>
  <script>
    var hoge = {
       a: '',
       x: window.alert('xss'),
       y: '',
       b: 'fuga'
    }; 

かくして見事にalertが表示されるわけですが、今時こんなでっかい穴が2年も放置されてたなんてビックリですよ。これを利用して偽のログイン画面に誘導し、IDとパスワードを奪うといった攻撃が可能だったのでしょう。

こんなコードが入り込んだのは、コードレビュー体制が整ってない時代だったから。入力値を見たら攻撃できないか?とか真っ先に考える自分みたいなヤバい人のチェックが入らなかったんだろう。レビュー重要。

それとシングルクオートをエスケープしないテンプレートエンジンは結構あります。JS界隈はシングルクオート派が多いのですが、HTMLファイルにJSを書く時は、動的出力も考慮してダブルクオートがいいかもしれんですね。