node v6 LTSリリース

node v6.9.0が新しいLTSライン(Boron)としてリリースされた。

Node v6.9.0 (LTS) | Node.js

v4系列からアップグレードするにあたって、大きな変更点は

  • ECMAScript機能の追加
  • Bufferコンストラクタの非推奨化
  • npm v3

その他はリンク先を参照。

新しいECMAScript機能

node v6系では import を除くECMAScript 2015 の仕様がほぼ網羅されている。さらにES2016のArray#includesも使用できる。

The spread operator for arrays and function calls(スプレッド演算子

const arr = [1, 2, 3];

function hoge(a,b,c) {
  return a + b + c;
}

hoge(...a);   // => 6

const arr2 = [...a, 4, 5];  // => [1, 2, 3, 4, 5]

Rest parameters(可変長引数)

function hoge(a, ...b) {
   return b.reduce((s, i) => s + i, a);
}

hoge(1, 2, 3, 4, 5);   // => 15

Default function parameters(デフォルト引数)

function hoge(a = 1, b = 2, c = 3) {
   return a + b + c;
} 

hoge(0)  // => 5
hoge(0, 0)  // => 3
hoge(0, 0, 0)   // => 0

Destructuring(分割代入)

const arr = [1, 2, 3, 4, 5];

const [a, b, ...rest] = arr;         // a => 1, b => 2, rest => [3, 4, 5]

const [c, d, e, f = 6] = rest;     // c => 3, d => 4, e => 5, f = 6
const obj = {a: 1, b: 2};

const {a, b} = obj;         // a => 1, y => 2

const {a: x, b: y} = obj;  // x => 1, y => 2

const {a: p, b: q, c: r = 3} = obj;  // p => 1, q => 2,  r => 3

プロキシ(とリフレクション)

const obj = {a: 1, b: 2, f: function() { return this.a + this.b }};

const p = new Proxy(obj, {
    get(target, property, receiver) {
        console.log('access property: ' + property);
        return target[property];
    }
});

console.log(p.f());
class Hoge {
    constructor(a) {
        this.a = a;
    }
}

const hoge = Reflect.construct(Hoge, [1]);
console.log(hoge instanceof Hoge);
console.log(hoge.a);

Array#includes

const arr = [1, 2, 3];

if (arr.includes(1)) {
   console.log('配列に1が含まれている');
}

Bufferコンストラクタが非推奨に

v6系では、セキュリティ上の理由からnew Buffer()が非推奨になっている。代わりに今後は Buffer.allocとBuffer.from を使えとのこと。

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を書く時は、動的出力も考慮してダブルクオートがいいかもしれんですね。