Created
August 11, 2015 14:04
-
-
Save sunib/6fbd3491deac3849a588 to your computer and use it in GitHub Desktop.
Very simple experiment to get started with RazorEngine lib.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace RazorExperiment | |
{ | |
using Microsoft.AspNet.Razor; | |
using RazorEngine.Templating; | |
using System; | |
using System.IO; | |
using System.Reflection; | |
using System.Security; | |
using System.Security.Permissions; | |
using System.Security.Policy; | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string result = ""; | |
// Option 1 (working but not isolated): | |
//SwitchAppDomain(); | |
//var service = Engine.Razor; | |
// Option 2 (working but not isolated): | |
//using (var service = RazorEngineService.Create()) | |
// Option 3 (working but not isolated): | |
//using (var service = IsolatedRazorEngineService.Create()) | |
// Option 4 (can't get it running, see SandBoxCreate function for more info): | |
using (var service = IsolatedRazorEngineService.Create(SandboxCreator)) | |
{ | |
result = DoingSomethingSimple(service); | |
Console.WriteLine(result); | |
Console.WriteLine("Executed simple compile, result={0}", result); | |
result = DoingSomethingBad(service); | |
Console.WriteLine("Whoops, sucesfully executed code that created a file at my pc! result={0}",result); | |
} | |
Console.WriteLine(result); | |
Console.ReadKey(); | |
} | |
/// <summary> | |
/// Have to do this according to the introduction, it works but it's not a sandbox. | |
/// https://antaris.github.io/RazorEngine/index.html#Temporary-files | |
/// </summary> | |
static void SwitchAppDomain() | |
{ | |
if (AppDomain.CurrentDomain.IsDefaultAppDomain()) | |
{ | |
// RazorEngine cannot clean up from the default appdomain... | |
Console.WriteLine("Switching to secound AppDomain, for RazorEngine..."); | |
AppDomainSetup adSetup = new AppDomainSetup(); | |
adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; | |
var current = AppDomain.CurrentDomain; | |
// You only need to add strongnames when your appdomain is not a full trust environment. | |
var strongNames = new StrongName[0]; | |
var domain = AppDomain.CreateDomain( | |
"MyMainDomain", null, | |
current.SetupInformation, new PermissionSet(PermissionState.Unrestricted), | |
strongNames); | |
var exitCode = domain.ExecuteAssembly(Assembly.GetExecutingAssembly().Location); | |
// RazorEngine will cleanup. | |
AppDomain.Unload(domain); | |
return; | |
} | |
// Continue with your code. | |
} | |
public static string DoingSomethingSimple(IRazorEngineService service) | |
{ | |
string template = "Hello @Model.Name, welcome to RazorEngine!"; | |
return service.RunCompile(template, "templateKey", null, new { Name = "World" }); | |
} | |
/// <summary> | |
/// A function that is doing a bad action, it can actually open up a file and write something. | |
/// As found on https://antaris.github.io/RazorEngine/Isolation.html | |
/// </summary> | |
/// <returns></returns> | |
public static string DoingSomethingBad(IRazorEngineService service) | |
{ | |
string result = ""; | |
string file = Path.Combine(Environment.CurrentDirectory, Path.GetRandomFileName()); | |
string template = @" | |
@using System.IO | |
@{ | |
File.WriteAllText(""$file$"", ""BAD DATA""); | |
}".Replace("$file$", file.Replace("\\", "\\\\")); | |
result = service.RunCompile(template, "test"); | |
return result; | |
} | |
/// <summary> | |
/// We have to create seperate domain shizzle to prevent hackers from beeing able abuse our templating power. | |
/// I would like to understand better how this works, just doing as told by this page now: https://antaris.github.io/RazorEngine/Isolation.html | |
/// </summary> | |
/// <returns>An AppDomain that you should use to execute the sandbox stuff.</returns> | |
public static AppDomain SandboxCreator() | |
{ | |
var evidence = new Evidence(); | |
evidence.AddHostEvidence(new Zone(System.Security.SecurityZone.Internet)); | |
var permissionSet = SecurityManager.GetStandardSandbox(evidence); | |
// You have to sign your assembly in order to get strong names (http://stackoverflow.com/questions/8349573/getting-null-from-gethostevidence) | |
// But doing this results in: | |
// Error 1 Assembly generation failed -- Referenced assembly 'RazorEngine' does not have a strong name D:\git\presence-engine\RazorExperiment\CSC RazorExperiment | |
// Error 2 Assembly generation failed -- Referenced assembly 'Microsoft.AspNet.Razor' does not have a strong name D:\git\presence-engine\RazorExperiment\CSC RazorExperiment | |
StrongName razorEngineAssembly = typeof(RazorEngineService).Assembly.Evidence.GetHostEvidence<StrongName>(); | |
StrongName razorAssembly = typeof(RazorTemplateEngine).Assembly.Evidence.GetHostEvidence<StrongName>(); | |
var appDomainSetup = new AppDomainSetup(); | |
appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; | |
var result = AppDomain.CreateDomain("Sandbox", null, appDomainSetup, permissionSet, razorEngineAssembly, razorAssembly); | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment