2013-09-26 3 views
1

잠재적 인 잘못된 코드 실행을 격리하기 위해 app-domain을 사용하여 샌드 박스을 만들려고합니다.개인 리터럴 필드에 대한 리플렉션 제한

을 제한하고 싶습니다.

나는 샌드 박스에이 방법을 짓고 있어요 : 그것은 개인 인스턴스 필드와 개인 특성을 가진 잘 작동하고

AppDomainSetup sandboxSetup = new AppDomainSetup 
{ 
    ApplicationBase = "." 
}; 
PermissionSet permissions = new PermissionSet(PermissionState.None); 
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 
AppDomain sandbox = AppDomain.CreateDomain("sandbox", null, sandboxSetup, permissions); 

: 샌드 박스에 액세스하려는 시도는 런타임에 의해 거부됩니다.

그러나 나는 그것이 문자 필드 (C#에서 const를)와 함께 작동하지 않는 것으로 나타났습니다 :

private const string PASSWORD = "secret"; 
private string password = "secret"; 
private string Password 
{ 
    get 
    { 
     return "secret"; 
    } 
} 
: 심지어 개인 경우 문자 필드의 값을 취득하는 것이 가능

비밀번호비밀번호이 제대로 보호되고 있지만 코드는 기본 반사와 PASSWORD의 값을 얻을 수 있습니다 :

string password = typeof(User).GetField("PASSWORD", BindingFlags.NonPublic | BindingFlags.Static).GetValue(currentUser) as string; // OK no problem take it, it's free! 

이 동작의 근거는 이해하고 싶습니다. 리터럴 값이 어셈블리에서 "쉽게"볼 수 있기 때문에 반사를 방지하는 것이 손실 전투이거나 최종 값이 실제로 "호출 된"보안 검사가 없으므로 ... 또는 ...?

이 예는 암호가 공유되지 않기 때문에, 정말 관련이없는하지만 비밀 값이 그런 식으로 암호화 또는 무언가에 사용되는 소금 값 상상 ... 당신의 도움을

감사합니다.

답변

2

상수로 FieldInfo을 얻으면 MdFieldInfo 유형이됩니다. 코드를 역 컴파일하면 해당 유형에 대한 보안 검사가 수행되지 않습니다. 당신이 RtFieldInfo 유형을 얻을 비 상수 값에 대한 FieldInfo을 얻을 때

[DebuggerHidden] 
[DebuggerStepThrough] 
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] 
public override object GetValue(object obj) 
{ 
    return this.GetValue(false); 
} 
[SecuritySafeCritical] 
private object GetValue(bool raw) 
{ 
    object obj = MdConstant.GetValue(this.GetRuntimeModule().MetadataImport, this.m_tkField, this.FieldType.GetTypeHandleInternal(), raw); 
    if (obj == DBNull.Value) 
    throw new NotSupportedException(Environment.GetResourceString("Arg_EnumLitValueNotFound")); 
    else 
    return obj; 
} 

그리고 그것은 보안 검사를 수행합니까 : 여기

MdFieldInfo 유형의 코드를 디 컴파일합니다. 여기

RtFieldInfo 유형의 코드를 디 컴파일 것 :

public override object GetValue(object obj) 
{ 
    StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 
    return this.InternalGetValue(obj, ref stackMark); 
} 

[SecuritySafeCritical] 
[DebuggerStepThrough] 
[DebuggerHidden] 
internal object InternalGetValue(object obj, ref StackCrawlMark stackMark) 
{ 
    INVOCATION_FLAGS invocationFlags = this.InvocationFlags; 
    RuntimeType runtimeType1 = this.DeclaringType as RuntimeType; 
    if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN) 
    { 
    if (runtimeType1 != (RuntimeType) null && this.DeclaringType.ContainsGenericParameters) 
     throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenField")); 
    if (runtimeType1 == (RuntimeType) null && this.Module.Assembly.ReflectionOnly || runtimeType1 is ReflectionOnlyType) 
     throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyField")); 
    else 
     throw new FieldAccessException(); 
    } 
    else 
    { 
    this.CheckConsistency(obj); 
    if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN) 
    { 
     RuntimeAssembly executingAssembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark); 
     if ((Assembly) executingAssembly != (Assembly) null && !executingAssembly.IsSafeForReflection()) 
     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", new object[1] 
     { 
      (object) this.FullName 
     })); 
    } 
    RuntimeType runtimeType2 = (RuntimeType) this.FieldType; 
    if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN) 
     RtFieldInfo.PerformVisibilityCheckOnField(this.m_fieldHandle, obj, this.m_declaringType, this.m_fieldAttributes, (uint) (this.m_invocationFlags & ~INVOCATION_FLAGS.INVOCATION_FLAGS_IS_CTOR)); 
    return this.UnsafeGetValue(obj); 
    } 
} 
+0

감사합니다 * 명시 적으로 보안 검사가 문자 필드에 구현되지 않는다는 것을 보여줍니다 디 컴파일 코드에 대한 뱌체슬라프 *. 주요 질문은 남아 있습니다 : 왜? +1 어쨌든 :) – Pragmateek