解説

インサイド .NET Framework [改訂版]

第9回 コード・アクセス・セキュリティ(その4)

吉松 史彰
2003/09/03
Page1 Page2 Page3 Page4 Page5 Page6 Page7

Demandメソッドの内部動作

 冒頭の例では、PermTestアセンブリにはFullTrustアクセス許可セットが適用されているものの、DBAccessアセンブリにはLocalIntranetアクセス許可セットが適用されているために、DBAccessアセンブリはSQL Serverにアクセスすることができなかった。では、もしこれが逆だったらどうなるだろうか。つまり、DBAccessアセンブリにはFullTrustのアクセス許可セットが適用され、PermTestアセンブリにはLocalIntranetなどの制限されたアクセス許可セットが適用されたら、果たしてSQL Serverにアクセスできるだろうか。

 結論をいうと、原則的にはアクセスできない(原則には例外があるのだが、それは後述する)。簡単に試すには、上記のDBAccessアセンブリをグローバル・アセンブリ・キャッシュ(GAC)に登録して、PermTest.exeをネットワーク共有(\\SERVER\SHARE)から実行すればよい。だが、アクセスできないのは不思議な気がしないだろうか。オブジェクト指向というのは、それぞれのクラスが自分自身の責任を果たし、外部にはどうやってその責任を果たしているのかは知らせないという考え方だ。DBAccessアセンブリがSQL Serverにアクセスしてデータを用意しようが、XMLファイルを読み取ってデータを用意しようが、PermTestのような呼び出し側には無関係だ。呼び出し側としては、どんな方法でもいいから、期待どおりの動作をしてくれればよい。それがオブジェクト指向というものではなかったか? そうだとすれば、実際にSQL ServerにアクセスするDBAccessアセンブリに対してアクセス許可が与えられていれば、PermTestアセンブリはそれを呼び出して結果を受け取ることができてもいいような気がしないだろうか。

 ところが、セキュリティの観点からは、オブジェクト指向とは少し異なる側面が見えてくる。SQL Serverにアクセスするには、System.Data.SqlClient名前空間のクラスを利用する。SqlConnectionクラスのOpenメソッドなどでアクセス許可のDemandが行われているのはすでに解説したとおりだ。ところで、System.Data.SqlClient名前空間のクラスは、System.Dataアセンブリに含まれていて、.NET Frameworkクラス・ライブラリを含むほかのアセンブリと同じくGACに登録されている。GACに登録されているということは、アセンブリはローカル・コンピュータからロードされることになるので、FullTrustのアクセス許可が適用されるということになる。

 もしもDemandメソッドによって調査されるアクセス許可の範囲が、それを呼び出したアセンブリだけに限定されていたら、インターネットからダウンロードされたアセンブリも含め、とにかくどんなコードでもSQL Serverにアクセスできることになる。Demandメソッドを呼び出すのはSqlConnectionクラスのOpenメソッドだからだ。つまり、そんなチェックは意味がないということになる。

 このため、Demandメソッドは「コールスタック」に含まれるすべてのアセンブリに対して、アクセス許可のチェックを行う。1つでもアクセス許可を得ていないアセンブリが見付かった場合、そこでゲーム・オーバーとなり、DemandメソッドはSecurityExceptionを発生させる。Demandメソッドは、Demandメソッドを呼び出したメソッドを呼び出したメソッド、そのメソッドを呼び出したメソッド、さらにそれを呼び出したメソッド……と、呼び出しの連鎖を逆にたどる作業を行う。この呼び出しの連鎖が「コールスタック」である。こうすることで、Demandメソッドに到達するまでに関与したすべてのアセンブリが洗い出され、そのアクセス許可がチェックされるのだ。

 最初の例の場合、SqlConnectionクラスのOpenメソッドを呼び出すと、その中でDemandメソッドが呼び出される。Demandメソッドはコールスタックを次の図1のように駆け上がり、DBAccessアセンブリがアクセス許可を持っていないことを突き止める。そこで例外が発生するわけだ。

図1 コールスタックにおけるアクセス許可のチェック(1)
DBAccess.TestメソッドはSqlConnectionクラスのOpenメソッドを呼び出し、その中でDemandメソッドが呼び出される。このメソッドでは呼び出しの連鎖であるコールスタックを順にたどっていき、アクセス許可のないアセンブリが見付かった時点でプログラムの実行はエラーとなる。

 逆に、PermTestアセンブリにFullTrustが与えられていない場合、DemandメソッドはDBAccessアセンブリを通り越してさらにPermTestアセンブリまでチェックし、やはりアクセス許可がないことを突き止める(図2)。このように、Demandメソッドがもれなくすべてのアセンブリをチェックするので、悪意のコードにむやみにSQL Serverのデータを読み取られるような心配はないわけだ。

図2 コールスタックにおけるアクセス許可のチェック(2)
アクセス許可のチェックはコールスタックを順にたどって行われるため、DBAccessアセンブリにFullTrustが与えられているが、PermTestアセンブリがそうでない場合でも、最終的にプログラムの実行は許可されない。
 

 INDEX
  解説 インサイド .NET Framework [改訂版]
  第9回 コード・アクセス・セキュリティ(その4)
    1.アクセス許可が適用されるタイミング
  2.Demandメソッドの内部動作
    3.属性によるアクセス許可チェックの指定
    4.型のロード時におけるチェック
    5.JITコンパイル時のチェックとDemandの動作の変更
    6.アクセス許可を取り戻す
    7.アセンブリ・レベルでの宣言セキュリティ
 
インデックス・ページヘ  「解説:インサイド .NET Framework [改訂版]」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間