安全性 ロード可能なアプレットを使用したプラットフォームのカーネルコードの変更

以下で説明するすべては、JavaScriptで実装されたクライアント部分のみに関係します。 技術的な性質に対する批判(たとえば、回避策)は歓迎されますが、「何のために、それが必要か」というスタイルに対する批判はありません。



アプレットを特定のプラットフォームに接続するモジュール(Hyperと呼びます)を開発すると、パッシブデータブロック(コンテンツ)に加えて、接続されたアプレットにもアクティブ(コード)が含まれるため、セキュリティタスクが表示されます。 そして、アクティブなブロックでは、不注意な開発者(攻撃者)がグローバルウィンドウオブジェクトにアクセスし、変数または重要なカーネルメソッドにアクセスし、置換を行うことができます。システムの動作には影響しませんが、ユーザーの個人データを傍受します。 将来、疑いを持たないユーザーは、ボブのガジェットのウォッチを使用します。このガジェットは、自分に関する情報を静かに収集するか、連絡先リストからアドレスにスパムを送信します。



グローバル変数の衝突の問題はすでに検討されており 、プラットフォームコアコードからロードされたコードを分離する解決策が提案されています。 グローバル名前空間に変数を作成すると、変数がウィンドウオブジェクトのプロパティになることは誰もが知っています。 たとえば、var a = 10; window.a = 10と同じ;



私たちのタスクは、サードパーティのスクリプトがカーネルコードにアクセスできないようにカーネルコードを分離することです。 分離は、匿名関数を作成し、この関数を即座に呼び出してローカル変数とオブジェクトを初期化することに基づいています。

例:(関数(){a = 10;})(); この関数は匿名であり、ウィンドウオブジェクトからは表示されません。



簡単なカーネルを取得しましょう:



var Core = {};

Core.sName = "MyCore" ;

Core.MyMethod = function(sMyValue){alert(sMyValue); }; *このソースコードは、 ソースコードハイライターで強調表示されました。


カーネルを分離します。



(関数(){

var Core = {};

Core.sName = "MyCore" ;

Core.MyMethod = function(sMyValue){alert(sMyValue); };

})(); *このソースコードは、 ソースコードハイライターで強調表示されました。




次に、アプレットのダウンロード機能を作成します。



Applet.Link = function(sCode、oContext){(new Function(sCode))。Call(oContext); }ここで



sCodeはアプレットの実行可能コードであり、oContextは重要なパラメーターです。 もっと広く見ると、これはデスクトップソフトウェアの世界のコンテキストの概念です。 保護モードでアセンブラーで書いた人は誰でもそれが何であるかを理解するでしょう。 つまり、コンテキストにはシステムの状態に関する情報が含まれています。 デスクトップアプリケーションでは、レジスタに関する情報がそこに保存されます。 システム自体の動作を中断することなく、アプリケーション自体がそれらを同時に変更できます。 この場合、コンテキストには、アプレットが機能するために必要な変数とプラットフォームオブジェクトが含まれています。 アプレットを実行用に起動するときのタスクは、コンテキストを形成することです。 これを行うには、アプレットコードに必要な変数とプラットフォームメソッドを知る必要があります。 すでに作成されたオブジェクトを検討します。 アプレットにCore名前空間のMyMethodメソッドが必要だとしましょう。

コンテキストを手動で作成します(Hyperではすべて自動化されており、xml形式のアプレット記述子と、インポートされた変数とオブジェクトをリストするImportBlockの概念があります)。 材料の同化に関する記事では、すべてが単純化されています。 コンテキストを取得します:var oContext = {MyMethod:Core.MyMethod)}。 これをすべてコードで結合します。



(関数(){



//コアモジュール。

var Core = {};

Core.sName = "MyCore" ;

Core.MyClass = function(){};

Core.MyClass.prototype.MyMethod = function(sMyValue){alert(sMyValue); };



//アプレットモジュール。

アプレット= {};

Applet.Link = function(sCode、oContext){( new Function(sCode))。Call(oContext); }



//アプレットモジュールをロードします。

var sCode = "this.MyMethod( 'Hello world');" ;

var oContext = {MyMethod:Core.MyMethod};

Applet.Link(sCode、oContext);



})(); *このソースコードは、 ソースコードハイライターで強調表示されました。


結果のコードはどうなりますか? コードを使用してアプレットが作成されます:this.MyMethod( 'Hello world'); このコードを持つ関数は、MyMethodプロパティを含むoContextオブジェクトのコンテキストで起動されたため、このプロパティは、これを介してこの関数の本体で使用可能になります。 アプレットは、テキストHello worldを含むアラートを表示します。 侵入者または無頓着な開発者に話を戻しましょう。

コード付きのアプレット#1が作成され、起動されました。



this .MyMethod = function(){alert( "Hack !!!" )};

this .MyMethod( 'Hello world !!!' ); *このソースコードは、 ソースコードハイライターで強調表示されました。


その結果、このアプレットはテキストHackを含むアラートを表示します。 アプレットはCore名前空間のメソッドを置き換えようとしていますが、実際にはコンテキスト内のメソッドのみを変更します。 したがって、同じメソッドを使用する別のアプレットは正常に機能します。



コードを含むアプレット#2が作成され、実行のために起動されます。



Core.MyMethod = function(){alert( 'Hack !!!'); };



ここで、攻撃者はCore.MyMethodを無頓着に変更しようとしましたが、Coreが定義されていないため、アプレットは失敗します。理由はわかっています。

そして今、コード全体:



(関数(){



//コアモジュール。

var Core = {};

Core.sName = "MyCore" ;

Core.MyMethod = function(sMyValue){alert(sMyValue); };



//アプレットモジュール。

アプレット= {};

Applet.Link = function(sCode、oContext){( new Function(sCode))。Call(oContext); };



//ハッカー#1からアプレットモジュールをロードします。

var sCode = "this.MyMethod = function(){alert( 'Hack !!!'); }; this.MyMethod( 'Hello world');”

var oContext = {MyMethod:Core.MyMethod};

Applet.Link(sCode、oContext);



//ハッカー#2からアプレットモジュールをロードします。

var sCode = “ Core.MyMethod = function(){alert( 'Hack !!!'); }; " ;

var oContext = {MyMethod:Core.MyMethod};

Applet.Link(sCode、oContext);



//適切な開発者からアプレットモジュールをロードします。

var sCode = "this.MyMethod( 'Hello world');" ;

var oContext = {MyMethod:Core.MyMethod};

Applet.Link(sCode、oContext);



})();

*このソースコードは、 ソースコードハイライターで強調表示されました。


重要!!! コンテキストを作成するとき、オブジェクトへのリンクがそこに到達しないことを確認する必要があります。そうしないと、悪意のあるアプレットがオブジェクト全体をメソッドで置き換え、プラットフォーム全体が悪意のあるコードで動作します。 この問題は、オブジェクト階層に沿ってインポートおよびコピーされるすべてを考慮したコンテキストを形成する関数を記述することで解決されます。



結論:アプレットを開発する機能を備えたプラットフォームの2番目のセキュリティ問題が検討されました。 最初は、グローバル名前空間での変数名の衝突です 。 別の3番目の問題があります:グローバルブラウザープロパティ(ウィンドウ、ドキュメントなど)へのアクセスですが、このトピックは別の記事用です。



All Articles