CA2147: 透過コードは、セキュリティ アサートを使用してはならない
TypeName |
SecurityTransparentCodeShouldNotAssert |
CheckId |
CA2147 |
[カテゴリ] |
Microsoft.Security |
互換性に影響する変更点 |
あり |
原因
SecurityTransparentAttribute とマークされたコードには、アサートに必要なアクセス許可が付与されません。
規則の説明
この規則では、100% 透過的なアセンブリまたは透過的/クリティカル混在のアセンブリ内のすべてのメソッドと型を分析し、宣言的または強制的に使用されている Assert にフラグを設定します。
実行時には、透過的なコードから Assert を呼び出すと、InvalidOperationException がスローされます。この状況は、100% 透過的なアセンブリで発生するだけでなく、透過的/クリティカル混在のアセンブリでも、メソッドまたは型が透過的と宣言されているにもかかわらず宣言的または強制的な Assert を含んでいる場合に発生することがあります。
.NET Framework 2.0 には、透過性と呼ばれる機能が導入されました。メソッド、フィールド、インターフェイス、クラス、および型を個別的に透過的またはクリティカルとすることができます。
透過的なコードでは、セキュリティ特権を昇格することはできません。したがって、透過的なコードに付与または要求されるアクセス許可は、自動的にコードを通じて呼び出し元またはホスト アプリケーション ドメインに渡されます。昇格の例として、Assert、LinkDemand、SuppressUnmanagedCode、unsafe コードなどがあります。
違反の修正方法
この問題を解決するには、Assert を呼び出すコードに対して SecurityCriticalAttribute を設定するか、Assert を削除します。
警告を抑制する状況
この規則によるメッセージは抑制しないでください。
使用例
SecurityTestClass が透過的である場合、Assert メソッドが InvalidOperationException をスローすると、このコードは失敗します。
using System;
using System.Security;
using System.Security.Permissions;
namespace TransparencyWarningsDemo
{
public class TransparentMethodsUseSecurityAssertsClass
{
// CA2147 violation - transparent code using a security assert declaratively. This can be fixed by
// any of:
// 1. Make DeclarativeAssert critical
// 2. Make DeclarativeAssert safe critical
// 3. Remove the assert attribute
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
public void DeclarativeAssert()
{
}
public void ImperativeAssert()
{
// CA2147 violation - transparent code using a security assert imperatively. This can be fixed by
// any of:
// 1. Make ImperativeAssert critical
// 2. Make ImperativeAssert safe critical
// 3. Remove the assert call
new PermissionSet(PermissionState.Unrestricted).Assert();
}
}
}
1 つの方法は、以下の例の SecurityTransparentMethod メソッドのコード レビューを行い、昇格に対して安全であると判断できる場合に、SecurityTransparentMethod メソッドをセキュリティ クリティカルとしてマークすることです。この方法では、メソッドとメソッド内の Assert において発生するすべての呼び出しに対し、詳細で完全なエラーのないセキュリティ監査を実行する必要があります。
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
[System.Security.SecurityCritical]
void SecurityCriticalMethod()
{
new FileIOPermission(PermissionState.Unrestricted).Assert();
// perform I/O operations under Assert
}
}
}
また、コードから Assert を削除し、後続のファイル I/O アクセス許可要求が SecurityTransparentMethod を通過して呼び出し元へ到達できるようにする方法もあります。これにより、セキュリティ チェックが有効になります。この場合、一般にはセキュリティ監査は必要ありません。アクセス許可要求が呼び出し元またはアプリケーション ドメインに送られるからです。アクセス許可要求は、セキュリティ ポリシー、ホスト環境、およびコード ソース アクセス許可の付与によって厳密に制御されます。