2009-04-08 4 views
2

나는 동적 어셈블리에 계산을 포함하는 소스 파일의 런타임 컴파일을 수행하는 C# 응용 프로그램을 가지고 있습니다. 분명히 이것은 심각한 보안 문제를 야기합니다. 다음 '식'에서 스레드를 다른 사용자로 실행할 수 있습니까? (.NET 2.0/3.5)

, 아래의 코드가 생성 될 것이고, 동적 어셈블리 생성 :

화학식 :

Int32 _index = value.LastIndexOf('.'); 
String _retVal = value.Substring(_index + 1); 
return _retVal; 

코드 생성 :

using System; 
namespace Dynamics 
{ 
    public class Evaluator 
    { 
    public Object Evaluate(String value) 
    { 
     // Begin external code 
     Int32 _index = value.LastIndexOf('.'); 
     String _retVal = value.Substring(_index + 1); 
     return _retVal; 
     // End external code 
    } 
    } 
} 

동적 어셈블리 그런 다음 Reflection을 통해 Evaluate 메서드가 실행됩니다. 위대한 작품.

문제는 악의적 인 코드 삽입의 가능성이 높기 때문에 관리되지 않는 API 호출없이 '샌드 박스'스레드에서 Evaluate 메소드를 실행하려고합니다. 는 테스트를 위해 나는 익명 Windows 사용자 내장 사용하고, 다음과 같은 코드로 올라와있다 :

Thread tSandbox = new Thread(
    new ParameterizedThreadStart(this.DoSandboxedEvaluation)); 
WindowsIdentity tIdentity = WindowsIdentity.GetAnonymous(); 
WindowsPrincipal tPrincipal = new WindowsPrincipal(i); 

이 나에게 익명의 사용자 ID 및 교장을 제공합니다. 이 스레드의 코드가 관리되지 않는 API 호출을 사용하지 않고 지정된 보안 컨텍스트에서 실행되도록 어떻게 tSandbox 스레드에 적용 할 수 있습니까?

감사합니다.

+0

관련 게시물 [https : //stackoverflow.com/questions/2608194/how-do-i-start-a-thread-in-a-different-security-context) – RBT

답변

1

만 익명 계정이 필요한 경우, 아주 가까이있을 수 있습니다 - 당신은 그냥 스레드 (당신이 스레드 내에서 실행중인 코드에서이 작업을 수행하는 원칙을 할당해야 System.Threading.CurrentPrinciple을 설정하여 변경하려는 경우)

그러나 Windows 사용자를 인증하고 해당 ID를 스레드에 할당해야하는 경우 LogonUser에 대한 관리되지 않는 호출을 만들어야한다고 생각합니다(). 나는 그 주위에 방법이 보이지 않는다.

다음은 익명 사용자 ("identityLabel"이라는 양식에 태그가 있고 ASP.Net 웹 ApplicationProject를 가정하고 onInit = "IdentityLabelInit"을 할당 한 코드)입니다. 코드가 IIS 또는 Cassini에서 실행되는지 여부에 따라 다르게 실행됩니다. IIS에서 초기 ID는 익명 사용자입니다 .Cassini에서 초기 신원은 나를 나타냅니다.

 

     protected void IdentityLabelInit(object sender, EventArgs e) 
     { 
      System.Threading.Thread testThread = new Thread(ReportIdentity); 
      testThread.Start(); 
      testThread.Join(); 
     } 

     private void ReportIdentity() 
     { 
      identityLabel.InnerText = "Initialized: " + System.Threading.Thread.CurrentPrincipal.Identity.Name; 
      System.Security.Principal.IPrincipal currentPrincipal = System.Threading.Thread.CurrentPrincipal; 
      SetAnonymousIdentity(); 
      System.Security.Principal.IPrincipal newPrincipal = System.Threading.Thread.CurrentPrincipal; 
      if (newPrincipal.Equals(currentPrincipal)) 
       identityLabel.InnerText += ("no change"); 
      else 
       identityLabel.InnerText += " | new name: " + System.Threading.Thread.CurrentPrincipal.Identity.Name; 
     } 

     private void SetAnonymousIdentity() 
     { 
      WindowsIdentity tIdentity = WindowsIdentity.GetAnonymous(); 
      WindowsPrincipal tPrincipal = new WindowsPrincipal(tIdentity); 
      System.Threading.Thread.CurrentPrincipal = tPrincipal; 
     } 
 
4

AFAIK 다른 사용자를 가장하는 유일한 방법은 관리되지 않는 win32 API (예 : LogonUser())를 사용하는 것입니다. interop을 통해 호출 할 수 있습니다.

의 코드 샘플있어이 here

+0

아마도 관리되지 않는 호출을 피하고 싶습니다. 나는 LogonUser와 모든 그 주위를 어지럽히지만, 나는 '더 나은'방법이 있는지 궁금 해서요 : 어쨌든 고마워요. – Dan

+0

예. 동일한 기능을 제공하는 매우 편리한 [nuget 패키지] (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) 및 [the post] (https://stackoverflow.com/a/7250145/465053) LogonUser()를 통해. – RBT

관련 문제