Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Checking if a JavaScript native function is monkey patched (2022)

2025年09月09日に「Hacker News」が公開したITニュース「Checking if a JavaScript native function is monkey patched (2022)」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

JavaScriptの組み込み関数が、外部から改変されていないか(モンキーパッチされていないか)を確認する技術について解説。プログラムが予期せぬ動作をしたり、セキュリティ上の問題が発生したりするのを防ぐ上で重要だ。

ITニュース解説

JavaScriptは、ウェブサイトやアプリケーションを動かすためのプログラミング言語であり、システムエンジニアが開発する上で非常に重要な役割を担っている。このJavaScriptには、最初から備わっている便利な機能がたくさんある。例えば、配列の最後に新しい要素を追加する Array.prototype.push や、JSON形式の文字列をJavaScriptのデータ構造に変換する JSON.parse、ユーザーにメッセージを表示する alert などだ。これらはJavaScriptの言語仕様の一部として提供されており、「ネイティブ関数」と呼ばれている。私たちが開発するプログラムの土台となる部分であり、通常は変更されることなく「本物」の機能として期待されるものだ。

しかし、JavaScriptの強力な特性の一つとして、プログラムの実行中に、これらのネイティブ関数や、他のライブラリが提供する関数を、開発者が自由に別の機能に「置き換える」ことができるという側面がある。この操作を「モンキーパッチ」と呼ぶ。モンキーパッチが行われると、例えば Array.prototype.push が本来の「要素を追加する」機能に加えて、裏で別の処理も実行する、あるいは全く異なる動作をするように書き換えられてしまう可能性がある。

モンキーパッチは、時として開発者に非常に役立つ。たとえば、利用している外部ライブラリにバグがあったり、特定の機能が不足していたりするが、そのライブラリのソースコードを直接修正できない場合、モンキーパッチを使えばその場で問題を修正したり、機能を追加したりできる。また、プログラムのデバッグを目的として、一時的に関数の挙動を変更するために用いられることもある。

しかし、モンキーパッチはその強力さゆえに危険も伴う。アプリケーションの「本物」の機能が書き換えられてしまうと、開発者が予期しない動作を引き起こし、バグの発生原因になったり、発生したバグの原因特定を非常に困難にしたりする。また、セキュリティの観点からも大きな問題となる。悪意のある攻撃者がシステムのセキュリティを侵害するために、ログイン処理やデータ検証に関わる重要な関数をモンキーパッチで改ざんし、意図しない挙動を引き起こす可能性があるからだ。このような状況を防ぎ、アプリケーションが安全で安定して動作することを保証するためには、ネイティブ関数がモンキーパッチによって改ざんされていないかを確認する方法を知っておくことが非常に重要になる。特に、多くの外部ライブラリやフレームワークを使用する大規模なシステム開発では、このような予期せぬ改ざんがないかをチェックすることが、システムの信頼性を保つ上で不可欠な作業となる。

モンキーパッチが適用されているかどうかを検出する方法はいくつか存在する。一つ目の方法は、関数の toString() メソッドを利用するものだ。JavaScriptのすべての関数は toString() というメソッドを持っており、これを呼び出すとその関数のソースコードを文字列として返してくれる。ネイティブ関数の場合、toString() を呼び出すと、例えば function push() { [native code] } のように、[native code] という特別な文字列を含む形式で結果が返されることがJavaScriptの仕様で定められている。これは、その関数がJavaScriptコードではなく、より低レベルな言語(例えばC++など)で実装された「本物」の関数であることを示している。一方で、モンキーパッチによってJavaScriptコードで書き換えられた関数は、その書き換えられた後の実際のJavaScriptコードが文字列として返される。したがって、関数の toString() の結果が [native code] を含んでいるかどうかをチェックすることで、その関数がネイティブであるか、それともモンキーパッチによって改ざんされたものであるかを、ある程度の確度で判断できる。この方法は手軽で分かりやすいが、完璧ではないという限界も理解しておく必要がある。なぜなら、悪意のある攻撃者は、関数の本体だけでなく、その toString() メソッド自体も改ざんして、あたかもネイティブ関数であるかのように偽装する可能性があるからだ。

より確実な方法として、二つ目に「別のグローバルコンテキストからの比較」という手法がある。これは、現在アプリケーションが動作している環境(これを「グローバルコンテキスト」と呼ぶ)とは完全に独立した、「きれいな」JavaScript実行環境を一時的に用意し、そこからネイティブ関数を取得して比較する方法だ。具体的な実装としては、ウェブページの中に「iframe(アイフレーム)」と呼ばれるHTML要素を一時的に作成する。このiframeは、現在のページとは独立したJavaScriptの実行環境を持っており、その内部ではネイティブ関数がモンキーパッチされていない「本物」の状態であると期待できる。そこで、この新しく作成したiframeの環境の中から、チェックしたいネイティブ関数(例えば Array.prototype.push)を取得する。そして、今私たちのアプリケーションが使っている Array.prototype.push と、iframeから取得した「本物」の Array.prototype.push が、まったく同じ関数であるかどうかを比較する。もし両者が異なっていれば、それは現在の環境で Array.prototype.push がモンキーパッチによって改ざんされていることを強く示唆している。この方法は、toString() メソッドが改ざんされているような、より巧妙なモンキーパッチに対しても有効であり、高い信頼性で改ざんを検出できる利点がある。ただし、一時的にiframeを作成し、それを管理する必要があるため、一つ目の toString() を利用する方法に比べて少し手間がかかり、パフォーマンスにわずかな影響を与える可能性もある。

JavaScriptにおけるモンキーパッチは、強力である一方で、システムの予期せぬ動作、バグ、さらにはセキュリティリスクを引き起こす可能性がある諸刃の剣だ。システムエンジニアとして、私たちが開発・運用するアプリケーションの信頼性と安全性を保つためには、このような改ざんが行われていないかを正確に検出する知識は不可欠だ。ネイティブ関数の toString() の出力形式をチェックする方法や、iframeのような独立した環境からネイティブ関数を取得して比較する方法は、モンキーパッチの検出に有効な手段である。これらの知識を身につけ、安全で安定したシステム構築に役立てることが、現代のシステムエンジニアには強く求められる。

関連コンテンツ