2009-04-08 5 views
2

Ich habe eine C# -Anwendung, die eine Laufzeitkompilierung von Quelldateien durchführt, die Berechnungen in dynamische Assemblys enthalten. Offensichtlich stellt dies ein ernsthaftes Sicherheitsproblem dar.Kann ein Thread als ein anderer Benutzer ausgeführt werden? (.NET 2.0/3.5)

Aus der folgenden 'Formel', würde der folgende Code erzeugt werden, und eine dynamische Assembly erstellt:

Formel:

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

generierter Code:

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 
    } 
    } 
} 

Die dynamische Montage wird dann geladen und die Methode Evaluate wird über Reflection ausgeführt. Das funktioniert großartig.

Das Problem ist, dass das Potenzial für die Injektion von bösartigem Code ist riesig, also möchte ich die Evaluate-Methode in einem "Sandboxed" -Thread ausführen (ohne API-Aufrufe nicht verwaltet). Zu Testzwecken verwende ich die in Anonymous Windows-Benutzern gebaut und habe mit dem folgenden Code kommen:

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

Das gibt mir die anonymen Benutzer Identität und Auftraggeber. Wie kann dies auf Thread tSandbox angewendet werden, sodass der Code in diesem Thread im angegebenen Sicherheitskontext ausgeführt wird, ohne Verwendung von Unmanaged API-Aufrufen?

Danke!

+0

Related post [hier] (https: //stackoverflow.com/questions/2608194/how-doi-i-start-a-thread-in-a-different-security-context) – RBT

Antwort

1

Wenn Sie nur das anonyme Konto benötigen, könnten Sie ziemlich nah dran sein - man muss nur das Prinzip auf den Thread zuweisen (Sie tun dies aus dem Code innerhalb des Fadens die Sie ändern möchten, indem Sie System.Threading.CurrentPrinciple) setzen

Wenn Sie jedoch einen Windows-Benutzer authentifizieren und dem Thread diese Identität zuweisen müssen, denke ich, dass Sie einen nicht verwalteten Aufruf an LogonUser vornehmen müssen(). Ich sehe das nicht anders.

Hier einige Code, der mit dem anonymen Benutzer arbeitet (er nimmt eine ASP.Net Web ApplicationProject, wo Sie einen Tag auf dem Formular mit dem Namen „identityLabel“ haben, und Sie haben zugewiesen onInit = „IdentityLabelInit“) (beachten Sie die Code läuft anders unter, ob Sie es unter IIS oder Cassini ausführen - unter IIS ist die ursprüngliche Identität der anonyme Benutzer. Unter Cassini war die ursprüngliche Identität ich.

 

     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 die einzige Möglichkeit, einen anderen Benutzer zu imitieren ist über die nicht verwaltete win32 API (z. B. LogonUser()) ... Sie können sie über Interop aufrufen.

Es gibt ein Codebeispiel dieses here

+0

Vielleicht hätte ich erwähnen sollen, dass ich nicht verwaltete Anrufe vermeiden möchte Ich könnte es mit LogonUser und all dem machen herumspielen das beinhaltet, aber ich fragte mich, ob es einen "besseren" Weg gab: p Danke trotzdem. – Dan

+0

Ja. Ein sehr praktisches [nugget-Paket] (https://www.nuget.org/packages/SimpleImpersonation/2.0.0) und [der Beitrag] (https://Stackoverflow.com/a/7250145/465053), um dasselbe zu erreichen über 'LogonUser()'. – RBT

Verwandte Themen