Skip to content

Instantly share code, notes, and snippets.

@sunib
Created August 11, 2015 14:04
Show Gist options
  • Save sunib/6fbd3491deac3849a588 to your computer and use it in GitHub Desktop.
Save sunib/6fbd3491deac3849a588 to your computer and use it in GitHub Desktop.
Very simple experiment to get started with RazorEngine lib.
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