コード アクセス セキュリティの基礎Code Access Security Basics

注意事項

コード アクセス セキュリティと部分的に信頼できるコードCode Access Security and Partially Trusted Code

.NET Framework には、コード アクセス セキュリティ (CAS) と呼ばれる、同一アプリケーションで実行される各種コードにさまざまな信頼レベルを強制的に適用するメカニズムが備わっています。The .NET Framework provides a mechanism for the enforcement of varying levels of trust on different code running in the same application called Code Access Security (CAS). .NET Framework のコード アクセス セキュリティは、コードの実行元や他の ID 情報に基づいてセキュリティ境界を適用するメカニズムとして使用しないでください。Code Access Security in .NET Framework should not be used as a mechanism for enforcing security boundaries based on code origination or other identity aspects. 現在、部分的に信頼されるコード (特に実行元が不明なコード) では、コード アクセス セキュリティと透過的セキュリティ コードがセキュリティ境界としてサポートされないように、ガイダンスを更新しています。We are updating our guidance to reflect that Code Access Security and Security-Transparent Code will not be supported as a security boundary with partially trusted code, especially code of unknown origin. 発生元の不明なコードの読み込みと実行に関しては、他のセキュリティ対策を適切に導入することなく行わないようにしてください。We advise against loading and executing code of unknown origins without putting alternative security measures in place.

このポリシーは .NET Framework のすべてのバージョンに適用されますが、Silverlight に含まれる .NET Framework には適用されません。This policy applies to all versions of .NET Framework, but does not apply to the .NET Framework included in Silverlight.

共通言語ランタイムに対応するすべてのアプリケーション (つまりすべてのマネージド アプリケーション) は、そのランタイムのセキュリティ システムと対話する必要があります。Every application that targets the common language runtime (that is, every managed application) must interact with the runtime's security system. マネージド アプリケーションのホストは、そのアプリケーションの起動時に、アプリケーションに対して一連のアクセス許可を付与します。When a managed application is loaded, its host automatically grants it a set of permissions. これらのアクセス許可は、ホストのローカル セキュリティ設定、またはアプリケーションが所属するサンドボックスによって決まります。These permissions are determined by the host's local security settings or by the sandbox the application is in. これらのアクセス許可に応じて、そのアプリケーションが正常に実行されるか、またはセキュリティ例外が生成されます。Depending on these permissions, the application either runs properly or generates a security exception.

デスクトップ アプリケーションの既定のホストでは、コードが完全な信頼を付与されて実行されます。The default host for desktop applications allows code to run in full trust. このため、アプリケーションの実行対象がデスクトップである場合は、アプリケーションに無制限のアクセス許可セットが付与されます。Therefore, if your application targets the desktop, it has an unrestricted permission set. その他のホストまたはサンドボックスでは、アプリケーションに対して制限付きのアクセス許可セットが付与されます。Other hosts or sandboxes provide a limited permission set for applications. アクセス許可セットはホストごとに異なる場合があるため、アプリケーションの設計時には、対象ホストで許可されているアクセス許可だけを使用するように注意する必要があります。Because the permission set can change from host to host, you must design your application to use only the permissions that your target host allows.

共通言語ランタイムに対応した有効なアプリケーションを作成するためには、次に示すコード アクセス セキュリティの概念を把握しておく必要があります。You must be familiar with the following code access security concepts in order to write effective applications that target the common language runtime:

  • タイプ セーフ コード: タイプ セーフコードは、適切に定義された、許可された方法でのみ型にアクセスするコードです。Type-safe code: Type-safe code is code that accesses types only in well-defined, allowable ways. たとえば、有効なオブジェクト参照を例として考えると、タイプ セーフ コードは、実際のフィールド メンバーに対応する固定オフセットが指すメモリ位置にアクセスできます。For example, given a valid object reference, type-safe code can access memory at fixed offsets that correspond to actual field members. オブジェクトがパブリックに公開するフィールドに属しているメモリの範囲外の、任意のオフセットが指すメモリ位置にアクセスするコードは、タイプ セーフとは言えません。If the code accesses memory at arbitrary offsets outside the range of memory that belongs to that object's publicly exposed fields, it is not type-safe. コードがコード アクセス セキュリティを活用できるようにするには、検証可能なタイプ セーフ コードを生成するコンパイラを使用する必要があります。To enable code to benefit from code access security, you must use a compiler that generates verifiably type-safe code. 詳細については、このトピックの後半の「検証可能なタイプ セーフ コードの記述」を参照してください。For more information, see the Writing Verifiably Type-Safe Code section later in this topic.

  • 強制構文と宣言構文: 共通言語ランタイムを対象とするコードは、アクセス許可を要求し、呼び出し元にアクセス許可を要求し、特定のセキュリティ設定をオーバーライドすることによってセキュリティ システムとやり取りできます (十分な特権が与えられています)。Imperative and declarative syntax: Code that targets the common language runtime can interact with the security system by requesting permissions, demanding that callers have specified permissions, and overriding certain security settings (given enough privileges). .NET Framework セキュリティ システムとプログラムによって対話するには、宣言構文および強制構文という 2 つの形式の構文を使用します。You use two forms of syntax to programmatically interact with the .NET Framework security system: declarative syntax and imperative syntax. 宣言的な呼び出しは属性を使用して実行され、強制的な呼び出しはコード内のクラスの新しいインスタンスを使用して実行されます。Declarative calls are performed using attributes; imperative calls are performed using new instances of classes within your code. 呼び出しには、強制的にだけ実行できるもの、宣言的にだけ実行できるもの、およびどちらの方法でも実行できるものがあります。Some calls can be performed only imperatively, others can be performed only declaratively, and some calls can be performed in either manner.

  • セキュリティで保護されたクラス ライブラリ: セキュリティ保護されたクラス ライブラリは、ライブラリの呼び出し元がライブラリが公開するリソースにアクセスするためのアクセス許可を持っていることを確認するためにセキュリティ要求を使用します。Secure class libraries: A secure class library uses security demands to ensure that the library's callers have permission to access the resources that the library exposes. たとえば、安全なクラス ライブラリにファイルを作成するメソッドがある場合、このメソッドにアクセスする呼び出し元には、ファイルを作成するためのアクセス許可が必要です。For example, a secure class library might have a method for creating files that would demand that its callers have permissions to create files. .NET Framework は、安全なクラス ライブラリで構成されています。The .NET Framework consists of secure class libraries. 作成するコードで使用するすべてのライブラリについて、アクセスするために必要なアクセス許可を確認する必要があります。You should be aware of the permissions required to access any library that your code uses. 詳細については、このトピックの後半の「セキュリティで保護されたクラス ライブラリの使用」を参照してください。For more information, see the Using Secure Class Libraries section later in this topic.

  • 透過的なコード: .NET Framework 4 以降、特定のアクセス許可を識別するだけでなく、コードを透過的セキュリティで実行するかどうかを決定する必要もあります。Transparent code: Starting with the .NET Framework 4, in addition to identifying specific permissions, you must also determine whether your code should run as security-transparent. セキュリティ透過コードは、セキュリティが重要な型またはメンバーを呼び出すことができません。Security-transparent code cannot call types or members that are identified as security-critical. この規則は、完全に信頼されているアプリケーションと、部分的に信頼されたアプリケーションの両方に対して適用されます。This rule applies to full-trust applications as well as partially trusted applications. 詳細については、「セキュリティ透過的なコード」を参照してください。For more information, see Security-Transparent Code.

検証可能なタイプ セーフ コードの作成Writing Verifiably Type-Safe Code

JIT (Just-in-time) コンパイルでは、検証プロセスが実行され、コードが調べられてタイプ セーフかどうかが判断されます。Just-in-time (JIT) compilation performs a verification process that examines code and tries to determine whether the code is type-safe. タイプ セーフであることが確認の際に証明されたコードは、検証可能なタイプ セーフ コードと呼ばれます。Code that is proven during verification to be type-safe is called verifiably type-safe code. 検証プロセスやコンパイラに制約があるために検証可能なタイプ セーフ コードではなくても、コードがタイプ セーフである場合があります。Code can be type-safe, yet might not be verifiably type-safe because of the limitations of the verification process or of the compiler. タイプ セーフではない言語もあり、Microsoft Visual C++ などの一部の言語コンパイラは、検証可能なタイプ セーフ マネージド コードを生成できません。Not all languages are type-safe, and some language compilers, such as Microsoft Visual C++, cannot generate verifiably type-safe managed code. 使用している言語コンパイラが検証可能なタイプ セーフ コードを生成するかどうかを確認するには、そのコンパイラのドキュメントを参照してください。To determine whether the language compiler you use generates verifiably type-safe code, consult the compiler's documentation. 特定の言語構成要素を回避するときにのみ、検証可能なタイプ セーフ コードを生成する言語コンパイラを使用する場合は、PEVerify ツールを使用して、コードが検証可能なタイプ セーフかどうかを判断できます。If you use a language compiler that generates verifiably type-safe code only when you avoid certain language constructs, you might want to use the PEVerify tool to determine whether your code is verifiably type-safe.

検証可能なタイプ セーフ コード以外のコードは、セキュリティ ポリシーによって検証を省略することを許可されている場合にだけ、実行を試行できます。Code that is not verifiably type-safe can attempt to execute if security policy allows the code to bypass verification. ただし、タイプ セーフは、アセンブリを分離するためのランタイムの機構において重要な要素であるため、コードがタイプ セーフの規則に違反している場合には、信頼度の高いセキュリティを確保することはできません。However, because type safety is an essential part of the runtime's mechanism for isolating assemblies, security cannot be reliably enforced if code violates the rules of type safety. 既定では、タイプ セーフでないコードは、その発生元がローカル コンピューターである場合にだけ実行できます。By default, code that is not type-safe is allowed to run only if it originates from the local computer. したがって、モバイル コードはタイプ セーフであることが必要です。Therefore, mobile code should be type-safe.

安全なクラス ライブラリの使用Using Secure Class Libraries

作成したコードが、クラス ライブラリにより要求されるアクセス許可を要求し、そのアクセス許可を与えられた場合には、そのコードからライブラリにアクセスでき、ライブラリが公開するリソースは承認されていないアクセスから保護されます。If your code requests and is granted the permissions required by the class library, it will be allowed to access the library and the resources that the library exposes will be protected from unauthorized access. コードが適切なアクセス許可を持っていない場合には、そのコードはクラス ライブラリにアクセスできないため、悪意のあるコードがそのコードを利用して保護されたリソースに間接的にアクセスすることもできません。If your code does not have the appropriate permissions, it will not be allowed to access the class library, and malicious code will not be able to use your code to indirectly access protected resources. 作成したコードを呼び出す他のコードも、ライブラリへのアクセス許可が必要になります。Other code that calls your code must also have permission to access the library. アクセス許可がない場合は、作成したコードの実行も制限されます。If it does not, your code will be restricted from running as well.

コード アクセス セキュリティを使用しても開発者によるコードの記述エラーがなくなるわけではありません。Code access security does not eliminate the possibility of human error in writing code. ただし、保護されているリソースにアクセスするときにアプリケーションが安全なクラス ライブラリを使用していれば、クラス ライブラリでセキュリティの問題が発生する可能性がないかどうかが詳しく調べられるため、アプリケーション コードに対するセキュリティ リスクも軽減されます。However, if your application uses secure class libraries to access protected resources, the security risk for application code is decreased, because class libraries are closely scrutinized for potential security problems.

宣言セキュリティDeclarative Security

宣言セキュリティ構文では、属性を使用して、コードのメタデータにセキュリティ情報を配置します。Declarative security syntax uses attributes to place security information into the metadata of your code. 属性は、アセンブリ、クラス、またはメンバーの各レベルに適用でき、使用する要求、確認要求、オーバーライドの種類を示します。Attributes can be placed at the assembly, class, or member level, to indicate the type of request, demand, or override you want to use. 要求は、共通言語ランタイムに対応するアプリケーションが、そのアプリケーションに必要なアクセス許可または必要ではないアクセス許可をランタイムのセキュリティ システムに通知するために使用します。Requests are used in applications that target the common language runtime to inform the runtime security system about the permissions that your application needs or does not want. 確認要求およびオーバーライドは、呼び出し元からリソースを保護できるようにしたり、既定のセキュリティ動作をオーバーライドしたりするために、ライブラリで使用されます。Demands and overrides are used in libraries to help protect resources from callers or to override default security behavior.

注意

.NET Framework 4 では、.NET Framework のセキュリティ モデルと用語に重要な変更が加えられており、この点は変更されました。In the .NET Framework 4, there have been important changes to the .NET Framework security model and terminology. これらの変更の詳細については、「セキュリティの変更」を参照してください。For more information about these changes, see Security Changes.

宣言セキュリティ呼び出しを行う前に、アクセス許可オブジェクトの状態データを、必要な特定形式のアクセス許可を表すように初期化する必要があります。In order to use declarative security calls, you must initialize the state data of the permission object so that it represents the particular form of permission you need. 組み込みの各アクセス許可は、開発者が実行するセキュリティ操作の種類を示す SecurityAction 列挙として渡される属性を持っています。Every built-in permission has an attribute that is passed a SecurityAction enumeration to describe the type of security operation you want to perform. しかし、アクセス許可は、それぞれに固有のパラメーターも受け入れます。However, permissions also accept their own parameters that are exclusive to them.

コードの呼び出し元がカスタム アクセス許可 MyPermission を持つことを要求する宣言構文の例を次のコード片に示します。The following code fragment shows declarative syntax for requesting that your code's callers have a custom permission called MyPermission. このアクセス許可は架空のカスタム許可であり、.NET Framework には実在しません。This permission is a hypothetical custom permission and does not exist in the .NET Framework. この例では、宣言呼び出しはクラス定義の直前に配置されており、このカスタム アクセス許可がクラス レベルで適用されることを示しています。In this example, the declarative call is placed directly before the class definition, specifying that this permission be applied to the class level. この属性には、呼び出し元が実行するためにこのアクセス許可を持っている必要があることを指定するSecurityAction.Demand構造体が渡されます。The attribute is passed a SecurityAction.Demand structure to specify that callers must have this permission in order to run.

<MyPermission(SecurityAction.Demand, Unrestricted = True)> Public Class MyClass1

   Public Sub New()
      'The constructor is protected by the security call.
   End Sub

   Public Sub MyMethod()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'This method is protected by the security call.
   End Sub
End Class
[MyPermission(SecurityAction.Demand, Unrestricted = true)]
public class MyClass
{
   public MyClass()
   {
      //The constructor is protected by the security call.
   }

   public void MyMethod()
   {
      //This method is protected by the security call.
   }

   public void YourMethod()
   {
      //This method is protected by the security call.
   }
}

強制セキュリティImperative Security

強制セキュリティ構文は、呼び出す対象のアクセス許可オブジェクトの新しいインスタンスを作成することによって、セキュリティ呼び出しを実行します。Imperative security syntax issues a security call by creating a new instance of the permission object you want to invoke. 強制構文を使用して確認要求とオーバーライドは実行できますが、要求は実行できません。You can use imperative syntax to perform demands and overrides, but not requests.

セキュリティ呼び出しを行う前に、アクセス許可オブジェクトの状態データを、必要な特定形式のアクセス許可を表すように初期化する必要があります。Before you make the security call, you must initialize the state data of the permission object so that it represents the particular form of the permission you need. たとえば、オブジェクトをFileIOPermission作成するときに、すべてのファイルへの無制限アクセスまたはファイルへのアクセス権を表すFileIOPermissionオブジェクトを初期化するコンストラクターを使用できます。For example, when creating a FileIOPermission object, you can use the constructor to initialize the FileIOPermission object so that it represents either unrestricted access to all files or no access to files. または、別のFileIOPermissionオブジェクトを使用して、オブジェクトが表すアクセスの種類 (読み取り、追加、または書き込み) と、オブジェクトで保護するファイルを示すパラメーターを渡すことができます。Or, you can use a different FileIOPermission object, passing parameters that indicate the type of access you want the object to represent (that is, read, append, or write) and what files you want the object to protect.

強制セキュリティ構文は、単一のセキュリティ オブジェクトを呼び出す他に、アクセス許可セット内のアクセス許可のグループを初期化するためにも使用できます。In addition to using imperative security syntax to invoke a single security object, you can use it to initialize a group of permissions in a permission set. たとえば、この方法は、1 つのメソッドで複数のアクセス許可に対してアサート呼び出しを確実に実行する唯一の方法です。For example, this technique is the only way to reliably perform assert calls on multiple permissions in one method. それには、PermissionSet クラスと NamedPermissionSet クラスを使用して、アクセス許可のグループを作成し、適切なメソッドを呼び出して必要なセキュリティ呼び出しを実行します。Use the PermissionSet and NamedPermissionSet classes to create a group of permissions and then call the appropriate method to invoke the desired security call.

強制構文を使用して確認要求とオーバーライドは実行できますが、要求は実行できません。You can use imperative syntax to perform demands and overrides, but not requests. アクセス許可の状態を初期化するために必要な情報を実行時にしか取得できない場合には、確認要求やオーバーライドを実行するときに、宣言構文の代わりに強制構文を使用します。You might use imperative syntax for demands and overrides instead of declarative syntax when information that you need in order to initialize the permission state becomes known only at run time. たとえば、呼び出し元に特定のファイルを読み取るためのアクセス許可が必要である場合に、読み取り対象のファイルの名前が実行時までわからないときには、強制確認要求を使用します。For example, if you want to ensure that callers have permission to read a certain file, but you do not know the name of that file until run time, use an imperative demand. また、条件を適用するかどうか、およびテストの結果に基づいてセキュリティ確認要求を実行するかどうかを実行時に決定する必要がある場合にも、宣言チェックの代わりに強制チェックを使用できます。You might also choose to use imperative checks instead of declarative checks when you need to determine at run time whether a condition holds and, based on the result of the test, make a security demand (or not).

コードの呼び出し元がカスタム アクセス許可 MyPermission を持つことを要求する強制構文の例を次のコード片に示します。The following code fragment shows imperative syntax for requesting that your code's callers have a custom permission called MyPermission. このアクセス許可は架空のカスタム許可であり、.NET Framework には実在しません。This permission is a hypothetical custom permission and does not exist in the .NET Framework. MyPermission の新しいインスタンスが MyMethod で生成され、このメソッドだけをセキュリティ呼び出しで保護します。A new instance of MyPermission is created in MyMethod, guarding only this method with the security call.

Public Class MyClass1

   Public Sub New()

   End Sub

   Public Sub MyMethod()
      'MyPermission is demanded using imperative syntax.
      Dim Perm As New MyPermission()
      Perm.Demand()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'YourMethod 'This method is not protected by the security call.
   End Sub
End Class
public class MyClass {
   public MyClass(){

   }

   public void MyMethod() {
       //MyPermission is demanded using imperative syntax.
       MyPermission Perm = new MyPermission();
       Perm.Demand();
       //This method is protected by the security call.
   }

   public void YourMethod() {
       //This method is not protected by the security call.
   }
}

マネージド ラッパー クラスの使用Using Managed Wrapper Classes

ほとんどのアプリケーションおよびコンポーネント (安全なライブラリ以外) では、アンマネージ コードを直接呼び出さないでください。Most applications and components (except secure libraries) should not directly call unmanaged code. 直接呼び出すべきではないいくつかの理由があります。There are several reasons for this. コードによってアンマネージ コードが直接呼び出されると、多くの状況では実行が許可されません。コードでは、ネイティブ コードを呼び出すための高い信頼レベルが付与されていなければならないためです。If code calls unmanaged code directly, it will not be allowed to run in many circumstances because code must be granted a high level of trust to call native code. ポリシーに変更が加えられ、こうしたアプリケーションの実行が許可される場合、アプリケーションではほとんどすべての操作を自由に実行できるようになり、システムのセキュリティがかなり脆弱になる恐れがあります。If policy is modified to allow such an application to run, it can significantly weaken the security of the system, leaving the application free to perform almost any operation.

さらに、アンマネージ コードにアクセスできるアクセス許可があるコードは、アンマネージ API を呼び出すことによってほとんどすべての操作を実行できるようになる可能性もあります。Additionally, code that has permission to access unmanaged code can probably perform almost any operation by calling into an unmanaged API. たとえば、アンマネージ コードを呼び出すアクセス許可を持FileIOPermissionつコードは、ファイルにアクセスする必要はありません。FileIOPermissionを必要とするマネージ ファイル API をバイパスして、アンマネージ (Win32) ファイル API を直接呼び出すだけです。For example, code that has permission to call unmanaged code does not need FileIOPermission to access a file; it can just call an unmanaged (Win32) file API directly, bypassing the managed file API that requires FileIOPermission. マネージド コードにアンマネージド コードを呼び出すアクセス許可があり、アンマネージド コードを実際に直接呼び出す場合、セキュリティ システムでは、ランタイムがアンマネージド コードに確実な制限を課すことができないため、セキュリティ制限の適用に信頼性が欠けることになります。If managed code has permission to call into unmanaged code and does call directly into unmanaged code, the security system will be unable to reliably enforce security restrictions, since the runtime cannot enforce such restrictions on unmanaged code.

アンマネージド コードにアクセスすることが必要な操作をアプリケーションで実行する場合、必要な機能 をラップする信頼できるマネージド クラス (存在する場合) を使用してそうした操作をアプリケーションで実行しなければなりません。If you want your application to perform an operation that requires accessing unmanaged code, it should do so through a trusted managed class that wraps the required functionality (if such a class exists). 安全なクラス ライブラリ内のラッパー クラスが既に存在する場合には、独自にラッパー クラスを作成しないでください。Do not create a wrapper class yourself if one already exists in a secure class library. ラッパー クラスでは、アンマネージ コードへの呼び出しが許可されるように高度な信頼が付与される必要があります。呼び出し元に適切なアクセス許可があることを確認要求する責任はラッパー クラスにあります。The wrapper class, which must be granted a high degree of trust to be allowed to make the call into unmanaged code, is responsible for demanding that its callers have the appropriate permissions. ラッパー クラスを使用する場合、作成したコードで必要となるのは、ラッパー クラスが確認要求するアクセス許可を要求して付与することのみです。If you use the wrapper class, your code only needs to request and be granted the permissions that the wrapper class demands.

関連項目See also