CA2108: 값 형식에서 선언적 보안을 검토하십시오.
TypeName |
ReviewDeclarativeSecurityOnValueTypes |
CheckId |
CA2108 |
범주 |
Microsoft.Security |
변경 수준 |
주요 변경 아님 |
원인
public 또는 protected 값 형식이 데이터 액세스 및 모델링 또는 링크 요청에 의해 보안됩니다.
규칙 설명
값 형식은 다른 생성자가 실행되기 전에 해당 기본 생성자에서 할당하고 초기화합니다. 값 형식이 Demand 또는 LinkDemand에 의해 보안되고 호출자에게 보안 검사를 만족하는 권한이 없으면 기본 생성자 이외의 모든 생성자가 실패하고 보안 예외가 throw됩니다. 값 형식은 할당 취소되지 않고 기본 생성자에서 설정한 상태로 유지됩니다. 값 형식의 인스턴스를 전달하는 호출자에게 인스턴스를 만들거나 인스턴스에 액세스할 수 있는 권한이 있으리라고 가정하지 마십시오.
위반 문제를 해결하는 방법
이 규칙 위반 문제를 해결하려면 형식에서 보안 검사를 제거하고 대신 메서드 수준의 보안 검사를 사용해야 합니다. 이러한 방식으로 위반 문제를 해결해도 적합하지 않은 권한을 갖는 호출자가 값 형식의 인스턴스를 얻는 것을 막을 수는 없습니다. 기본 상태에서 값 형식의 인스턴스가 중요한 정보를 노출하지 않는지, 그리고 악용될 소지가 없는지 확인해야 합니다.
경고를 표시하지 않는 경우
모든 호출자가 보안에 위협을 가하지 않고 기본 상태에서 값 형식의 인스턴스를 얻을 수 있으면 이 규칙에서 경고를 표시하지 않을 수 있습니다.
예제
다음 예제에서는 이 규칙을 위반하는 값 형식이 들어 있는 라이브러리를 보여 줍니다. StructureManager 형식에서는 값 형식의 인스턴스를 전달하는 호출자가 인스턴스를 만들고 인스턴스에 액세스할 수 있는 권한이 있다고 가정합니다.
using System;
using System.Security;
using System.Security.Permissions;
[assembly:AllowPartiallyTrustedCallers]
namespace SecurityRulesLibrary
{
// Violates rule: ReviewDeclarativeSecurityOnValueTypes.
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public struct SecuredTypeStructure
{
internal double xValue;
internal double yValue;
public SecuredTypeStructure(double x, double y)
{
xValue = x;
yValue = y;
Console.WriteLine("Creating an instance of SecuredTypeStructure.");
}
public override string ToString()
{
return String.Format ("SecuredTypeStructure {0} {1}", xValue, yValue);
}
}
public class StructureManager
{
// This method asserts trust, incorrectly assuming that the caller must have
// permission because they passed in instance of the value type.
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Assert, Name="FullTrust")]
public static SecuredTypeStructure AddStepValue(SecuredTypeStructure aStructure)
{
aStructure.xValue += 100;
aStructure.yValue += 100;
Console.WriteLine ("New values {0}", aStructure.ToString());
return aStructure;
}
}
}
다음 응용 프로그램에서는 라이브러리의 약점을 보여 줍니다.
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using SecurityRulesLibrary;
// Run this test code with partial trust.
[assembly: System.Security.Permissions.PermissionSetAttribute(
System.Security.Permissions.SecurityAction.RequestRefuse,
Name="FullTrust")]
namespace TestSecurityExamples
{
public class TestDemandOnValueType
{
static SecuredTypeStructure mystruct;
[STAThread]
public static void Main()
{
try
{
mystruct = new SecuredTypeStructure(10,10);
}
catch (SecurityException e)
{
Console.WriteLine(
"Structure custom constructor: {0}", e.Message);
}
// The call to the default constructor
// does not throw an exception.
try
{
mystruct = StructureManager.AddStepValue(
new SecuredTypeStructure());
}
catch (SecurityException e)
{
Console.WriteLine(
"Structure default constructor: {0}", e.Message);
}
try
{
StructureManager.AddStepValue(mystruct);
}
catch (Exception e)
{
Console.WriteLine(
"StructureManager add step: {0}", e.Message);
}
}
}
}
이 예제의 결과는 다음과 같습니다.