prototype pollution attack

Javascript現在の仕様になった歴史的な経緯や背景を深掘りしワンランク上の評価ができるようになろう

投稿日: カテゴリー: IT技術
Pocket

過去にプロトタイプ汚染について記事にした際、Javascriptに関して深掘りした記事を書きたいと思って1年以上が経過していることに気がつきました。
Javascript、歴史的な経緯から現在の仕様になった背景を鑑みて、正負共々等身大の評価を見積もりれるような記事を目指したいと思います。

javascriptの特性を理解すれば利用すべきjavascriptの絞り込みやプロトタイプ汚染などの特有の脆弱性の発見などリスク発見などに役立つ見識が得られるはずです。

またMicrosoftか!!JavascriptとJScript互換性を持たせるECMAScript(ECMA International TC39)が策定された経緯

Javascriptは1995年にCookieで有名なNetscapeのNetscape Navigatorというウェブブラウザのスクリプト言語として現在Mozillaに所属するBrendan Eich(ブレンダン・アイク)氏らによって開発されました。
その後、Microsoftはブラウザスクリプトの需要が高まりを認識しつつもJavascriptのライセンス料金を払いたくなかったため、Internet Explorer用のウェブブラウザのスクリプト言語としてJScriptを開発を開発しました。サービス提供者は挙動の違いを埋めるべく仕様の違いを追いつつける不毛な闘いに追われることなりました。

例えば通信用のオブジェクトのコンストラクタでは以下のように記載が異なる

Netscape Navigator(Javascript)

Javascriptで通信用のオブジェクトのコンストラクタ new XMLHttpRequest();

Microsoft Internet Explorer (JScript)

JScript通信用のオブジェクトのコンストラクタ new ActiveXObject(“MSXML2.XMLHTTP”);

IEは独自仕様がただですら多くデザイナーやエンジニアが死んでしまうため、Webエンジニアの苦境を救うべくJavascriptとJScript互換性を持たせるECMAScriptが策定(ECMA International TC39)されました。
Javascriptの全てではなくJavascriptのコアな部分だけ仕様として切り出してきたものをECMAScriptという標準仕様として策定され、各種ブラウザで実装されるようになりました。
その後、Ajaxなどの新しい技術が登場し、JavascriptはWebサイトをより高度なものにしたり、Webアプリケーションを開発するための有力なツールとして広く使われるようになりました。

Javascriptの一部の仕様がECMAScriptという特性は環境によって同じJavascriptであってもできることが大きく異なるということを示します。

ブラウザ環境→ECMAScript+Web APIs(DOM API+Web API+Feach API+ XHR API+WebRTCe.t.c)
Node.jsの環境→ECMAScript+CommonJS
ブラウザ拡張→ECMAScript+(Chrome、Firefoxアドオン)
スマホアプリ→ECMAScript+(Apache Cordva、Monaca)
Adobe CC→ECMAScript+(Adobe JSX)
MS Office→ECMAScript+(Office JavaScript API )

特にリスクの評価などの際はコア部分(ECMAScript)と組み合わさるAPIやライブラリ、アクセスリソースを把握するために実行環境を確認することが重要となることを留意する必要があります。

Livinig Standard:機能ごとに仕様を策定し順次最新版に追加していく(🔗ここをチェックする)
Strawman アイデアレベル
Proposal 機能提案・検討
Draft 仕様の暫定
Candidate 開発中
Finish 仕様決定→ここまでできた機能がどんどん追加される

 

Javascript活用されているフレームワーク、オープンソース、ライブラリの例と概要

Javascriptを利用したフレームワーク:

– React:Facebookが開発したJavaScriptのWebアプリケーションを構築するためのライブラリ
– Angular:Googleが開発したJavaScriptのWebアプリケーションを構築するためのフレームワーク
– Vue.js:オープンソースのJavaScriptのWebアプリケーションを構築するためのフレームワーク
– Ember.js:SproutCoreのYehuda Katz氏が開発したCoC(設定より規約:Ruby on Railsが有名)の理念で作られたJavaScriptのWebアプリケーションを構築するためのフレームワーク
– Node.js:Ryan Dahlにより開発されたGoogleのV8 JavaScriptエンジンをベースにしたJavaScriptのランタイム環境で「Express」「Meteor」「Sails」フレームワークと組み合わせWebアプリケーションを構築することが一般的

Javascriptを利用したオープンソース:

– jQuery:JavaScriptのライブラリで、Web開発を簡単に行うためのツールです。DOM操作やAJAX通信などを簡単に行うことができます。
– Underscore.js:2009年にJeremy Ashkenasによって開発されたJavaScriptのコレクション操作を支援するライブラリ
– D3.js:データ可視化のためのJavaScriptライブラリ
– Socket.io:2010年にGuillermo Rauchによって開発されたWebSocketを使用してリアルタイムWebアプリケーションを作成するためのライブラリ
– Express.js:2010年にTJ Holowaychukによって開発された¥Node.jsのWebアプリケーションフレームワーク

Javascriptを利用したライブラリ:

– Lodash:2009年にJohn-David Daltonによって開発されたJavaScriptのコードをより簡潔に書くためのツール
– Moment.js:2011年にIsaac Z. Schlueterによって開発されたJavaScriptのデータフォーマットと時間操作を簡単に行えるようにするためのライブラリ
– Chart.js:2013年にNick Downieによって開発されたデータを可視化するためのオープンソースのJavaScriptライブラリ
– Axios:2014年にMatt Zabriskieによって開発されたJavaScriptのHTTPクライアントを書くためのライブラリ、Node.jsを使用して開発されている
– RxJS:2010年にMicrosoftの.NET開発チームが開発した、イベント駆動型プログラミングモデル

 

Javascriptエンジンとブラウザの関係を理解する

大前提、コンピュータはJavascriptを動かすことができません。Javascriptを動かすためのプログラム、ランタイムが動いてJavascriptに従って動いているかのように処理を実現しているに過ぎません。もう少し正確に説明すると例えば、Javascriptのブラウザでの実行原理は、JavaScriptエンジンがコードを解析し、それを機械語に変換し、それをCPUが実行するというものです。JavaScriptエンジンは、コードを解析し、それを機械語に変換するためのコンパイラを持っています。コンパイラは、コードを解析し、それを機械語に変換するために、コードを解析し、それを機械語に変換しコンピュータがその命令を処理します。

ブラウザの動作をおさらいする

悪意のあるスクリプトの実行と抽象的な表現ではなく、ユーザーの確立されたセッション データまたはブラウザーの localStorage からのデータの盗み取り、ユーザーをだまして意図しないアクションを実行させる、Web アプリケーションのソース コードの脆弱性を悪用する

ブラウザ実行環境(JavascriptからWeb APIsを通してブラウザを操作する)
Networking
User Interface
UI Backend
Rendering Engine
Browser Engine
Javascript Engine
Chorme:V8(Nodejsでも動作する→Universal Javascript)
Safari:javascriptCore
Firefox:SpiderMonkey
Edge:Chakra→V8
Data Storage

ナビゲーション→DNS ルックアップ→TCP のハンドシェイク→TLS ネゴシエーション→TCP スロースタート / 14kB ルール→輻輳制御→DOM ツリーの構築

まずはページが生成されるきっかけとしてユーザーが URL をアドレスバーに入力したり、リンクをクリックしたり、またはフォームを送信したりといったナビゲーションというアクションをトリガーにします。次にブラウザーが DNS ルックアップをリクエストし、そのリクエストは最終的にネームサーバーによって処理され、ネームサーバーが IP アドレスを返します。この最初のリクエストの後、多くの場合その IP アドレスはしばらくの間キャッシュされ、ネームサーバーへ再接続する代わりにキャッシュから IP アドレスを取得することによって、後続するリクエストの速度を向上させるのに活用します。TLS ネゴシエーションは、通信の暗号化に使用する暗号の種類を決定し、サーバーを認証し、実際のデータ送信が始まる前に安全な通信の準備を整えるフェーズです。

ウェブサーバーへのコネクションが確立された後、初めに行われるのがスロースタートです(スローは投げる方の)。スロースタートとはパケット転送に使用できる帯域幅を検出する方法でネットワークの最大容量が見つかるまで、拡散される情報量を徐々に増やしつつ実行されます。


パース処理でネットワークから受信したデータを DOM と CSSOM に変換します

1. クロスブラウザの問題:
https://www.webdesignerdepot.com/2015/10/the-problem-with-javascript-cross-browser-compatibility/

Javascriptが実行されるまで
Javascript Engine(コードの実行前に Code、Global Object、thisが必要)
Code
Global Object:
Windowオブジェクト(ここにWeb APIsが含まれている)→一個しか存在しない(生成・削除の操作は不可)
ブラウザのコンソール(Command+Option+i)で 「>window」と打つとオブジェクトが存在するのが分かります。
alertやbtoa(Base64),onClickなどが生成されていることが確認できます(すぐ使える関数が確認できる)
グローバル変数はdelete演算子で削除することができず、グローバルプロパティはdelete演算子で削除ができます。
this:オブジェクトへの参照を保持している
実行コンテキスト
①グローバルコンテキスト
②関数コンテキスト
③evalコンテキスト(非推奨ですが存在はしているので・・一応)
コールスタック

ホイスティング

 

JavaScriptはプロトタイプベースの言語であること、プロトタイプオブジェクトの概念が理解されていないことが悪用されている
JavaScript では、クラスではなくプロトタイプに基づいたオブジェクト
クラスはオブジェクトの集まりを特徴付けるすべてのプロパティを定義します。クラスを具体化し親クラスのプロパティを保持したものをインスタンスとします。一方、プロトタイプベースの言語では、この区別がなくオブジェクトだけがあります。そして新しいオブジェクトの初期プロパティの取得元になるテンプレートとして使用されるオブジェクトをプロトタイプオブジェクト (prototypical object) と呼びます。
どのオブジェクトも別のオブジェクトに対するプロトタイプとして関連づけることができます。さらにオブジェクト作成時にも実行時問わずどのオブジェクトも独自のプロパティを指定できます。
クラスベース言語ではクラスをコンパイル時に生成し、コンパイル時または実行時にクラスのインスタンスを作成します。クラス定義後に、そのクラスのプロパティの数や型を変更することはできません。これに対し JavaScript では、どのオブジェクトでも実行時にプロパティの追加や削除ができます。ある一連のオブジェクトでプロトタイプとして使用されているオブジェクトにプロパティを追加すると、それをプロトタイプとするオブジェクトにも新しいプロパティが追加できます。
プロトタイプベースの言語はどの作成・実行どのタイミングでも別のオブジェクトに対するプロトタイプとして関連づけプロパティの追加・削除が行えるため、クラスベース言語のインスタンスのように生成元のプロパティのままが保持されているとは限らない
プロトタイプチェーンの理解
この仕様を理解していない場合、信用できないプロパティを処理に使用してしまう可能性が考えられます。この悪用方法をプロトタイプ汚染攻撃(prototype pollution attack)と言います。

Object.freezeで変更不可にする(具体的にはObject.freeze(Object.prototype);)
__proto__, __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__の読み取り・書き込みのアクセスを禁止する
プロトタイプ言語のプロパティは書き換わる前提で開発を行い、制御が困難と感じたら特に企業で提供するサービスでは無理せず代替手段を検討させる

 

 

以上です。参考になりましたら幸いです。