Node.js セキュリティリリース(2021年7月)
Node.jsのセキュリティリリースが行われました。現行バージョンの全てが影響範囲となり、Node.jsを利用している全てのシステムはアップデートを行う必要があります。
2021/07/29
Node.jsのセキュリティリリースが行われました。このセキュリティリリースにはUse after free on close http2 on stream canceling 脆弱性対応が行われています。
- サーバー側でプログラムを実行する仕組みの一つ
- ブラウザで利用されているJavaScirptをサーバー側で実行することができる
- ChromeブラウザのJavaScriptエンジンV8を利用しているので高速
- 性質上インターネットに直接さらされるため脆弱性には素早い対応が必要
影響範囲
All versions of the 16.x, 14.x, and 12.x releases lines
https://nodejs.org/en/blog/vulnerability/july-2021-security-releases-2/
このセキュリティ更新対象は12, 14, 16全てのバージョンとなり、すべてのユーザーは速やかにアップデートを行う必要があります。
13.x, 15.x はすでにサポートが終了しているため更新対象としてはリストされていませんが、同じコードが利用されているため同様の問題が発生するハズです。
運用環境でこれらのバージョンのnode.jsを利用している場合は速やかにサポート対象バージョンに変更する必要があります。
CVE-2021-22930
脆弱性レポートでおなじみのCVEレコードが作成されています。しかし8月5日時点では詳細は非公開となっています。
問題点
今回のセキュリティリリースで対応した問題はUse-After-Freeと呼ばれるもので、プログラム中でのメモリ管理に問題がありました。
Use-After-Freeは略してUAFと呼ばれる事もあります。
UAF
プログラムは実行時に様々なデータや実行コード自体もメモリ上に確保・展開し、はじめて利用可能になります。
Use-After-Free攻撃はその名の通り、プログラムからすでに解放したメモリ領域に攻撃者にとって都合の良い内容を設定し、その領域をプログラム中から参照させることにより任意のコード等を実行する手法になります。
しかし単に解放されたメモリでは攻撃者の都合よく参照させることが難しいためメモリは解放されたものの、そのメモリ領域を指しているポインターが残っている状態を悪用し攻撃します。
シェルコードなどが埋め込まれる事が多く、適切なメモリ領域にそのコードを配置するためのメモリ埋め(ヒープスプレー)などと合わせて行われる事が多い。
プログラムの通常の動作では、なかなかこのような状況を発生させることは出来ないため多くのUAFはエラー処理のバグを突いた形で行われているケースが多くあります。
しかし、ブラウザではJavaScriptのような処理系が用意されているため比較的容易にUAFの状況を作り出すことが可能であったため、ブラウザ等のユーザーコードが実行される環境では数々の対策が行われています。
今回はUAFの状況を作り出すために特定タイミングでhttp2での通信を状態を切断することにより発生させることが可能なようです。
Node.jsでの問題点
Node.js is vulnerable to a use after free attack where an attacker might be able to exploit the memory corruption, to change process behavior.
July 2021 Security Releases
Node.jsはこの脆弱性により、メモリが破壊されプロセスの動作を変更できる可能性があるとしています。
つまりnode.jsのプロセスをエラーで落とす事や、任意のコード実行できる可能性があります。
We normally like to give advance notice and provide releases in which the only changes are security fixes, but since this vulnerability was already public we felt it was more important to get this fix out fast in releases that were already planned.
July 2021 Security Releases
しかしNode.js側もこの脆弱性がすでに公になっていることを認識していたため、通常であれば事前にアナウンス行い、セキュリティ修正のみのリリースを行いますが、事前に予定されていた今回のリリースに含める形としたようです。
CVE等ではあくまでも非公開となっていますが、脆弱性を利用することが可能な実証コードが公開されてしまうことも少なくありません。
メモリの解放
話は脆弱性とは逸れますが、プログラムから確保したメモリを使う必要が無くなった際は、そのメモリを解放する必要があります。
しかしそのメモリ解放をし忘れる事をメモリリークと呼び、メモリを使い果たしてしまった場合はシステムが不安定になります。
一般的にほぼ全てのOSはメモリが不足した場合、システムが停止することを避けるため一定のメモリ領域をストレージに書き込みメモリ空間を解放し、そのデータが必要となったタイミングでまたメモリ領域に書き戻しを行う仕組みがあります。これをスワップと呼びます。
メモリ不足が深刻になり、スワップ領域に逃がすこともできない場合OOM(Out of memory) Killerにより大きなメモリ領域を確保しているプロセスが停止させられます。しかしこのOOM Killerは時として運用しているシステムにとって重要なプロセスを停止させる場合もあり、この状況に陥らないようにすることが大切です。
C/C++などの言語ではプログラマーの責任において利用しなくなったメモリを開放する必要がありますが、Javaなどの言語ではGC(Garbage Collector)と呼ばれる仕組みにより自動的にメモリが開放されます。
次のセキュリティリリース
すでに2021年8月11日(およそ2週間後)にセキュリティリリースが予定されており、今回の問題はそのリリースタイミングまで待てないという判断がなされています。
脆弱性が見つかるタイミングや、詳細がどの程度公開されるかは運の部分も大きいため今回は若干タイミングが悪かったなという印象です。
まとめ
このような状況が多発すると、クラウドのフルマネージドサービスは自動で更新してくれてたりするので便利かな〜と思っていまいます。
References
- July 2021 Security Releases https://nodejs.org/en/blog/vulnerability/july-2021-security-releases-2/
- CVE-2021-22930 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22930
- プログラムローダにより UAF 攻撃を抑制する手法の提案と実装 https://ipsj.ixsq.nii.ac.jp/ej/index.php?action=pages_...