先日セキュリティレビューを受けました.脅威モデルに関してはおかげさまで無事通過(一箇所指摘を受けたけど).ただAPTCAに関する質問があって,はじめて聞く言葉だったのでまったく答えられませんでした…orz
APTCAって何かを説明するには,その前にコード アクセス セキュリティ(CAS)を理解しておく必要があります.でもこれが難しいんですよね.そんなわけでこれから書くAPTCAの説明には誤りを含んでいる可能性があります.もしこの日記を読む人がいたら,そのあたりを十分気をつけてくださいね.
アセンブリには厳密名をつけると思います.いや検証用のプログラムを書くときなんかは厳密名なんてつけないですけど,まぁ一般的には付けるってことで.で,厳密名をつけたアセンブリ(a)を他のプログラム(b)が呼び出すとき,(b)はCASでいうところのFullTrust権限がついていないとSecurity例外が発生します.こんなときには(a)にAPTCA属性を付けると例外を回避できます.
実際のソースコードで確認しましょう
呼び出される側(a):厳密名をつけるほう
using System; using System.Collections.Generic; using System.Text; namespace CalcAdd { public class Calc { public int Add(int a, int b) { return a + b; } } }
呼び出し側(b):
using System; using System.Collections.Generic; using System.Text; using CalcAdd; namespace CalcDriver { class Program { static void Main(string[] args) { int a = 10; int b = 5; Calc calc = new Calc(); Console.WriteLine("{0} + {1} := {2}", a, b, calc.Add(a,b)); } } }
[コントロールパネル]-[管理ツール]-[.NET Framework 2.0 Configuration]より,[My Computer]-[Runtime Security Policy]-[User]-[Code Groups]-[All_Code]でPermission setをFullTrustからEverythingに変更すると……
Unhandled Exception: System.Security.SecurityException: アセンブリは部分的に信頼されている呼び出し元を許可しません。
場所 System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, Object demand, IPermission permThatFailed)
場所 CalcDriver.Program.Main(String[] args)
失敗した操作:
LinkDemand
失敗したアセンブリまたは AppDomain:
CalcDriver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
失敗したアセンブリのゾーン:
MyComputer
失敗したアセンブリの URL:
file:///C:/work/0817/CalcDriver/bin/Release/CalcDriver.exe
となります.
ここで(a)の側のAssemblyInfo.csの最終行に以下の行を追加します.
[assembly: System.Security.AllowPartiallyTrustedCallers()]
すると
10 + 5 := 15
と例外を回避できます.
ただし例外を回避できました,めでたしめでたしってわけでもないんですよね.APTCAはせっかくあるCASのセキュリティポリシーに例外(制限事項)を設けることになるので脆弱性につながる可能性がある.したがって十分注意して運用しないといけませんよ……ということだったみたいです>セキュリティレビュー.うちのプロジェクトではAPTCAは一切使ってないので,問題なしって答えればよかったんですね.うーむ…orz
しかし…そろそろ本格的に.NET Framework自体の勉強しないとなぁ.