I was able to solve this by NOT using RazorEngine
, but make my own implementation (based on some code frome there).
The main problem with RazorEngine
is the following:
For the CodeDomProvider
needed to compile the razor template you need a "Full Trust" AppDomain
, but the IsolatedTemplateService
does execute "everything" in the new AppDomain
so it fails compiling the template.
I solved this by splitting this up into two parts:
- Compiling the template
- Rendering the template
Step one I do in the "main AppDomain
" and only step 2 in the "restricted AppDomain
".
There was then one additional problem:
If you compile the template "in memory" (=> without generating a *.dll
file), which is done by RazorEngine
, it is directly loaded in the current AppDomain
which I did not want as it "inherits" that domains permissions then.
Because of this I disabled this and generate a *.dll
in a "common templates folder".
So after the compilation I have a *.dll
file containing the template which is not loaded anywhere yet.
The second AppDomain
is created with the following permission set:
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, templatePath));
permSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
The first permission is needed to execute any code, the second is to allow the AppDomain
to load the generated assembly from my common templates folder and the third is for limited support for reflection (only in the loaded assembly, but not i.e. in System.*
) to support dynamic
so I can use a ViewBag
.
Every thing else is prohibited:
- no file access outside
templatePath
- no network access
- no SQL Server access
I then call a Render
method in this restricted domain which loads the appropriate assembly and renders the template. This method also supports a timeout, after which the rendering is killed, to avoid while (true) ;
DOS attacks like suggested by Kris.
This seems to work fine so far. I did now release this as IsolatedRazor
including a NuGet package. May RazorEngine
can incorperate this as e.g. RestrictedIsolatedTemplateService
or so...