How dangerous is it to let users specify RazorEngine templates?
Asked Answered
S

3

6

I have mail-merge like functionality, which takes a template, some business object, and produces html which is then made into PDF.

I'm using RazorEngine to do the template+model to html bit.

If I let the users specify the templates, what risks am I taking? Is it possible to mitigate any risks?

For example, could the users execute arbitrary code? (delete files, alter database, etc.?) Is there some way I can detect this sort of thing? (I know that would be impossible generally, but the bits of code in the razor template should be model property gets, or possibly if statements based on model property values).

I do basically trust the users here (it's a small private project), but as templating engines go, this one seems excessively powerful for this application.

Socher answered 14/10, 2011 at 11:34 Comment(0)
E
5

A cshtml Razor file is able to execute any. NET code in the context of the site so yes, it is a security risk to permit them to be supplied by users.

You would be better served by accepting a more general HTML template, with custom tokens to input Model data.

Expiratory answered 14/10, 2011 at 12:10 Comment(1)
Thanks. I'm looking elsewhere for a templating engine now. It did feel like Razor was insecure in this application, but I didn't find anyone making this warning (and there are plenty of articles about how to use it for mail merge).Socher
B
11

In version 3 I've introduced an IsolatedTemplateService which supports the parsing/compiling of templates in another AppDomain. You'll be able to control the creation of the application domain that templates will be compiled in, which means you can introduce whatever security requirements you want by applying security policies to the child application domain itself.

In future pushes, I am hoping to introduce a generic way for adding extensions to the pipeline, so you can do things like code generation inspection. I would imagine this will enable scenarios for type checking of the generated code before it is compiled.

I pushed an early version of RazorEngine (v3) onto GitHub a few days ago. Feel free to check it out. https://github.com/Antaris/RazorEngine

Backward answered 14/10, 2011 at 13:17 Comment(1)
Thanks, I'll keep an eye on RazorEngine - it seems really useful (but not for this application, at this time).Socher
E
5

A cshtml Razor file is able to execute any. NET code in the context of the site so yes, it is a security risk to permit them to be supplied by users.

You would be better served by accepting a more general HTML template, with custom tokens to input Model data.

Expiratory answered 14/10, 2011 at 12:10 Comment(1)
Thanks. I'm looking elsewhere for a templating engine now. It did feel like Razor was insecure in this application, but I didn't find anyone making this warning (and there are plenty of articles about how to use it for mail merge).Socher
L
1

I believe that having removed using statements and replacing any @System.[...] like System.IO.File.Delete(filepath) using regex can reduce a fair amount of possible security holes.

Keep in mind that the Template runs inside a context and can access only what is available in it but that includes also .NET Framework assemblies.

Labiodental answered 14/10, 2011 at 12:9 Comment(4)
@{ using System.IO;} With out trying I would suspect that code to work just fine and I'm sure ther'll be other clever ways to beat almost any regex. It's unsecure and better to build something simple secure from scratch I'd sayCinerator
That's true. But the only way that someone can use .NET libraries is to write using System.[...] or using NS = System.[...] or type the full namespace. (I can't think another way for now). Nevertheless I agree that it's dangerous but everything comes with a trade off and if someone must use RazorTemplates I believe taking care of .NET Lib is a good start.Labiodental
I'm sure you could do some funky stuff with reflection, if you were trying really hard to beat the regexes... ...although you'd need to call something directly at some point, I suppose.Socher
@RuneFS - that particular example won't work as code blocks become part of the Execute method body.Backward

© 2022 - 2024 — McMap. All rights reserved.