LoginSignup
0
1

More than 3 years have passed since last update.

Node.js セキュリティアップデート + Node.js v15 について

Posted at

Node.js セキュリティアップデートが出てた

https://nodejs.org/en/

2.23 に、Node.js の新しいバージョンがでたのでチェックしよう。
https://nodejs.org/en/blog/vulnerability/february-2021-security-releases/

10.x, 12.x, 14.x 15.x 用のセキュリティアップデート

重大(1), 高い深刻度(1), 低い深刻度(1)

  1. HTTP/2 の unknownProtocol があまりにも多くなった時、DoS 攻撃を受ける可能性がある問題
    • ファイルシステムが漏洩する可能性
    • メモリリークを引き起こす可能性
  2. localhost6 がホワイトリストに含まれている場合、DoS 攻撃を受ける可能性がある問題
  3. OpenSSL の脆弱性が Node.js を介して悪用される可能性がある問題

適宜追従しましょう(フロントエンドだけなら別にって感じだけど)。

Nodejs 10.x は 2021.4.30 にサポート終了予定、12.x 系は 2022.4.30 で終了予定
※奇数バージョンは機能開発用バージョンで、偶数バージョンは長期サポートバージョン。最新 15.x 以外の奇数はない

Node.js のバグ報告について

nodejs-sec グループ
https://groups.google.com/g/nodejs-sec?pli=1

バグ報告の方法
https://github.com/nodejs/node/blob/master/SECURITY.md

Nodejs にバグを報告するとお金もらえるプログラム:バグバウンティプログラム
https://hackerone.com/nodejs


Node.js v15 について

Node.js v15 あまりキャッチアップしてなかったので、おさらいしてみました。

https://nodejs.org/en/

v15 のリリースは 2020.10.21。v16 は 2021.4 とかですかね。

公式 Medium
https://nodejs.medium.com/node-js-v15-0-0-is-here-deb00750f278

codedamn さんのまとめ YouTube
https://www.youtube.com/watch?v=OIzGI5wFiXg

めっちゃまとまってる
https://shisama.hatenablog.com/entry/2020/10/21/004612

1. npm 7 が同梱

npm 7 が入った。

https://www.npmjs.com/package/npm

  • workspace という概念が入った
    • monorepo で作りたい時とかは便利そう
  • acceptDependencies という概念も入った
  • peerDependencies の挙動変更
  • npx が実行前に確認されるようになった
  • npm audit の表示方法が変更
  • package.exports が npm の内部モジュールを参照できないようになった
  • npm test の表示内容が変更
  • npm buildnpm unbuild が廃止

https://blog.watilde.com/2020/10/14/npm-v7の主な変更点まとめ/

2. unhandledRejection の挙動変更

ブレイキングチェンジ!

  • unhandledRejection の挙動が変わった。default warn だったのが throw になった。

ただそもそもこれが起きてる時は以下のタイミングで

  • Promise を使った非同期処理において想定外のエラーが起きた
  • エラーハンドリングが漏れている
  • 単純なコードのエラー

マズイプログラムになっているはずなので、挙動が変更になることでより安全なコードが書けるようになった。

https://zenn.dev/kimamula/articles/b32d11d52c2b7a733119

unhandledRejection について

https://medium.com/@hagevvashi/unhandledrejectionについて-70739d2b6a60

Web サービスを運営していると、Sentry を使ってエラーハンドリングしたりすると思う

https://sentry.io/welcome/

window.onerror は、Promise.reject() によって投げられたエラーは拾わない
(ただし console.error() 形式で表示はされる)

Promise を使うエラー(Node.js でファイル操作だとかをするときの I/O 処理や、ブラウザで API 通信の失敗)を検知する時に使う。

try {
  await axios.post("/some-resources");
} catch(e) {
  // error handling
  throw e; // this causes unhandled rejection
}
window.addEventListener("unhandledrejection", (e: PromiseRejectionEvent): void => {
  // an error loginng
  logError(e.reason);
});
process.on("unhandledRejection", (error: {} | null | undefined, promise: Promise<any>) => {
  // an error loging
  logError(error);
})

https://medium.com/@hagevvashi/unhandledrejectionについて-70739d2b6a60

3. ES2021 に対応

JavaScript エンジンの V8 が v8.6 にアップデート。まぁでもブラウザでは既に使えるので珍しくはない

Promise.any

Promise.all は、全部が resolved になった時 / どれかが rejected になった時エラー

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'foo');
});

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values);
  })
  .catch(() => {
    console.log("error");
  });
// expected output: Array [3, 42, "foo"]

Promise.race は、どれかが resolved になった時 / どれかが rejected になった時エラー
Promise.allSettled は、全部が resolvedrejected になった時 / エラーにはならない
Promise.any は、どれかが resolved になった時 / 全部が rejected になった時エラー

10 個の Promise を走らせて、9 個失敗しても、最後の 1 つが成功なら成功としたい時(race だとどれかが reject になるとエラーになっちゃう)に使う

WeakRefs

Garbage Collection 時に破棄できるオブジェクトを作れる。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

var ref = new WeakRef(element)
ref.deref() // 参照元を取り出す

簡単にサンプルを作ってみた。↓
https://playcode.io/740665/

タイマーが動き続けている。別のタイマーで DOM 要素を 5 秒後に remove する。元のタイマー関数では参照はできている。Garbage Collection されると参照がきえて止まる。

メモリリークを防ぐコードが書ける。

AggregateError

複数のエラーをまとめたい時に使う。

try {
  throw new AggregateError([
    new Error("some error"),
  ], 'Hello');
} catch (e) {
  console.log(e instanceof AggregateError); // true
  console.log(e.message);                   // "Hello"
  console.log(e.name);                      // "AggregateError"
  console.log(e.errors);                    // [ Error: "some error" ]
}

エラーを配列で与えられる。

Logical Assignment Operators 論理代入演算子

読みにくくなるからやめてほしいw

let a = true
a &&= false // x && (x = y): x と y が true な値の場合、y の値が代入される
// false
a
// false
a ||= true // x || (x = y): x が false な値の場合、y の値が代入される
// true
a
// true
a = null
a ??= 1 // x ?? (x = y): x が null or undefined な値の場合、y の値が代入される
// 1
a
// 1
a ??= 2
// 1
a
// 1

Numeric separators

桁が読みやすくなるから積極的に使おう。

123 === 1_2_3
// true
1_000_000_000.000_001
// 1000000000.000001

ただこんなでかいマジックナンバー扱いたくないし扱う機会もない気がする。

String.prototype.replaceAll

ブラウザで使えるようになってたやつ。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
https://caniuse.com/mdn-javascript_builtins_string_replaceall

IE 11 は Babel を通せば replaceAll が書かれたコードはトランスパイルしてくれる。preset-env (core-js) を使うことで IE11 でも動く。

https://v8.dev/features/string-replaceall

ちなみに Next.js は @babel/preset-env 入ってないので IE11 対応させるなら config で指定する。

4. Web Crypto API

JavaScript で暗号化・復号・署名・検証ができる Web 標準 API。

https://caniuse.com/cryptography

ブラウザでは昔っから使えたやつ。
Node は最近ブラウザで使えたやつが使えるようになってきているといういい話。

5. AbortController

Web リクエストを中止することができるグローバルユーティリティオブジェクトの AbortController が Node.js 15 でも使えるようになった。

const ac = new AbortController();
ac.signal.addEventListener('abort', () => console.log('Aborted!'),
{ once: true });
ac.abort();
console.log(ac.signal.aborted);  // Prints True

動画のダウンロードを中止する例

https://developer.mozilla.org/en-US/docs/Web/API/AbortController

var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

fetch はまだ Node.js に実装されてないけどね。

フロントエンドの UI 開発で、ボタンに対しての mousedown/mouseup イベントを addEventListen していて、クリック後画面遷移してしまうので removeEventListen しておきたい時、abortController を使えば一発で解除できるテクがどっかで紹介された。

6. Event Target

ブラウザで使えた EventTarget が Node.js でも使えるようになった。Event の発行・伝播はブラウザでは EventTarget、Node.js では EventEmitter を使っていた。

https://nodejs.org/api/events.html#events_eventtarget_and_event_api

const target = new EventTarget();

target.addEventListener("foo", (event) => {
  console.log("foo is called");
});

const ev = new Event("foo");
target.dispatchEvent(ev);

イベントが DOM ツリーを伝って伝播が行われないなど差はあるが、ユニバーサルなプログラムが書けるようになってきている。

7. N-API updated

Node.js のネイティブ拡張をするための Node API (通称 N-API) がアップデート。C 言語のインターフェース。まぁ使うことはあまりないのかなぁ。

https://nodejs.org/api/n-api.html#n_api_node_api

8. QUIC (実験的機能)

UDP ベースの通信プロトコル「QUIC」が使用できるようになった。
TLS 1.3 ベースでのセキュリティ、フロー制御、エラー訂正、接続、多重化とかとか。

TLS 1.3 とは: https://kinsta.com/jp/blog/tls-1-3/

HTTP/3 サーバーを作ることができる。
https://blog.leko.jp/post/http-over-quic-on-nodejs15/

むずすぎてよくわからんですね

かんそう

  • せめて Node.js 14.x にはしとこう
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1