C# Code in einer isolierten Umgebung ausführen?
Ich habe eine ASP .NET Core Web API und bekomme C# Code an einen Endpoint. Ich möchte diesen Code ausführen und den return-Wert an den User zurückgeben. Wie ist es mir möglich den Code in einer isolierten Umgebung auszuführen, sodass der Code keine Auswirkungen auf meine Maschine hat? Ich habe die Lib Microsoft.CodeAnalysis verwendet. Das Ausführen funktioniert. Problem ist eben nur, dass es nicht in einer abgesicherten Umgebung passiert. Klar, ich könnte eine zusätzliche API in einer VM machen, aber das wäre die letzte Option, die ich in Erwägung ziehen würde.
1 Antwort
Im besten Fall verzichtest du darauf, Nutzern solche Schnittstellen an die Hand zu geben. Es ist schwierig, jegliches Sicherheitsrisiko einzukalkulieren.
Bei so einem Unterfangen sollte es zum einen eine Validation/Filterung und Limitation geben, als auch eine Ausführung in einem ausgelagerten Kontext (Stichwort: Sandbox).
Bezüglich Ersterem würde ich wohl nur Codesnippets in einer stabilen Zeichenkodierung (wie UTF-8) annehmen und diese in eine existierende Methode einfügen. Ein Zugriff auf andere Elemente außerhalb (das inkludiert die Methode selbst) sollte verhindert werden. Ein Mittel zur Umsetzung könnte eine zufallsgenerierte Benamung aller Klassen, Methoden, u.ä. sein.
Die verfügbaren Namespaces würde ich stark einschränken und vielleicht auch eine Whitelist für Schlüsselbegriffe und Operatoren anlegen. Eine maximale Zeichenanzahl wäre ebenso sinnvoll und es sollte einen Filter für unmanaged Code geben.
Für die Code-Ausführung könnte der Expression Evaluator C# Eval Expression zum Einsatz kommen. Den kannst du entsprechend vorkonfigurieren (max. Iterationsanzahl von Schleifen, SafeMode, ...). Vielleicht gibt es noch andere, bessere Alternativen, doch danach müsstest du selbst recherchieren.
Die Möglichkeit, eine Sandbox-Umgebung zu erstellen, bot Microsoft nur für das .NET-Framework (lies: How to run partially trusted code in a sandbox) an. Der Support wurde mit .NET Core allerdings nicht fortgesetzt. Stattdessen wird für solche Fälle angeraten, auf OS-Funktionen zurückzugreifen (wie z.B. die Windows Software Restriction Policies / Virtualisierung / Container (s. Windows Sandbox) / Benutzerkonten).
Bei Try.NET handelt es sich um eine Blazoranwendung. Das heißt, die Ausführung findet im Browser (bzw. in dessen Sandbox) als WASM-Modul statt und ist daher funktional auf die technischen Einschränkungen des Browsers limitiert (im Grunde so wie JavaScript). Ob du damit deine eigentlichen Zielanforderungen erfüllen kannst, kann ich nicht beurteilen. Wenn ja, würdest du eine eigene API, die C#-Code extra annimmt, jedenfalls nicht mehr benötigen.
Was hältst du von der Library Try .NET? Ist sowas empfehlenswert?
https://github.com/dotnet/try/tree/main