CA2114: 메서드 보안은 형식의 상위 집합이어야 합니다.
항목 | 값 |
---|---|
RuleId | CA2114 |
범주 | Microsoft.Security |
주요 변경 내용 | 주요 변경 |
원인
형식에 선언적 보안이 있고, 해당 메서드 중 하나에 동일한 보안 작업을 위한 선언적 보안이 있으며, 보안 작업이 링크 요청이 아니고, 형식으로 검사된 권한이 메서드로 검사된 권한의 하위 집합이 아닙니다.
참고 항목
이 규칙은 더 이상 사용되지 않습니다. 자세한 내용은 사용되지 않는 규칙을 참조하세요.
규칙 설명
메서드에 동일한 작업을 위한 메서드 수준의 선언적 보안과 형식 수준의 선언적 보안이 둘 다 있으면 안 됩니다. 두 검사는 결합되지 않고 메서드 수준의 요청만 적용됩니다. 예를 들어 형식이 X
권한을 요청하고 해당 메서드 중 하나가 Y
권한을 요청하는 경우 코드에 X
권한이 없어도 메서드를 실행할 수 있습니다.
위반 문제를 해결하는 방법
코드를 검토하여 두 작업이 모두 필요한지 확인합니다. 두 작업을 모두 필요한 경우 메서드 수준의 작업에 형식 수준에서 지정된 보안이 포함되어 있는지 확인합니다. 예를 들어 형식이 X
권한을 요청하고 해당 메서드도 Y
권한을 요청해야 하는 경우 메서드에서 X
와 Y
를 명시적으로 요청해야 합니다.
경고를 표시하지 않는 경우
형식에서 지정된 보안이 메서드에 필요하지 않은 경우 이 규칙의 경고를 표시하지 않아도 됩니다. 그러나 일반적인 경우는 아니므로 신중하게 디자인을 검토해야 할 수 있습니다.
예 1
다음 예제에서는 환경 권한을 사용하여 이 규칙을 위반하는 경우의 위험을 보여 줍니다. 이 예제에서 애플리케이션 코드는 형식에 필요한 권한을 거부하기 전에 보안 형식의 인스턴스를 만듭니다. 실제 위협 시나리오에서는 애플리케이션이 개체 인스턴스를 얻을 수 있는 또 다른 방법이 필요합니다.
다음 예제에서 라이브러리는 형식에 대한 쓰기 권한과 메서드에 대한 읽기 권한을 요청합니다.
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
namespace SecurityRulesLibrary
{
[EnvironmentPermissionAttribute(SecurityAction.Demand, Write="PersonalInfo")]
public class MyClassWithTypeSecurity
{
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool SetEnvironmentVariable(
string lpName,
string lpValue);
// Constructor.
public MyClassWithTypeSecurity(int year, int month, int day)
{
DateTime birthday = new DateTime(year, month, day);
// Write out PersonalInfo environment variable.
SetEnvironmentVariable("PersonalInfo",birthday.ToString());
}
[EnvironmentPermissionAttribute(SecurityAction.Demand, Read="PersonalInfo")]
public string PersonalInformation ()
{
// Read the variable.
return Environment.GetEnvironmentVariable("PersonalInfo");
}
}
}
예제 2
다음 애플리케이션 코드는 형식 수준의 보안 요구 사항을 충족하지 않는 경우에도 메서드를 호출하여 라이브러리의 취약성을 보여 줍니다.
using System;
using System.Security;
using System.Security.Permissions;
using SecurityRulesLibrary;
namespace TestSecRulesLibrary
{
public class TestMethodLevelSecurity
{
MyClassWithTypeSecurity dataHolder;
void RetrievePersonalInformation(string description)
{
try
{
Console.WriteLine(
"{0} Personal information: {1}",
description, dataHolder.PersonalInformation());
}
catch (SecurityException e)
{
Console.WriteLine(
"{0} Could not access personal information: {1}",
description, e.Message);
}
}
[STAThread]
public static void Main()
{
TestMethodLevelSecurity me = new TestMethodLevelSecurity();
me.dataHolder = new MyClassWithTypeSecurity(1964,06,16);
// Local computer zone starts with all environment permissions.
me.RetrievePersonalInformation("[All permissions]");
// Deny the write permission required by the type.
EnvironmentPermission epw = new EnvironmentPermission(
EnvironmentPermissionAccess.Write,"PersonalInfo");
epw.Deny();
// Even though the type requires write permission,
// and you do not have it; you can get the data.
me.RetrievePersonalInformation(
"[No write permission (demanded by type)]");
// Reset the permissions and try to get
// data without read permission.
CodeAccessPermission.RevertAll();
// Deny the read permission required by the method.
EnvironmentPermission epr = new EnvironmentPermission(
EnvironmentPermissionAccess.Read,"PersonalInfo");
epr.Deny();
// The method requires read permission, and you
// do not have it; you cannot get the data.
me.RetrievePersonalInformation(
"[No read permission (demanded by method)]");
}
}
}
이 예제는 다음과 같은 출력을 생성합니다.
[All permissions] Personal information: 6/16/1964 12:00:00 AM
[No write permission (demanded by type)] Personal information: 6/16/1964 12:00:00 AM
[No read permission (demanded by method)] Could not access personal information: Request failed.
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기