I'm using RazorLight in my web application where the user can provide mail templates in Razor syntax.
However this means that the user can do stuff like this
@{
var i = 0;
while (true)
{
i += 1;
<p>Line @i</p>
}
}
which causes my web application to crash at some point - or stuff like this
@using System.IO
@{ var f = File.ReadAllText(@"/etc/passwd"); }
@f
which is also really bad.
What can I do to prevent such attacks? Is it possible to run the Razor engine in a sandbox?
For full .NET it is possible to run razor in isolated AppDomain, but I don't really know what can we do with .NET Core, as there is no AppDomain. I will investigate this question
Yeah I know the missing AppDomain is a really severe restriction in .Net Core. And in fact I'm using .Net Core for my project...
Thanks for having a look at this!
Small suggestion: Why not execute the untrusted code in a Docker container?
I'm also interested in sanboxing capabilities using Dotnet core. I don't think running the untrusted code within containers is a great idea for various reasons, one of them being:
One primary risk with running Docker containers is that the default set of capabilities and mounts given to a container may provide incomplete isolation, either independently, or when used in combination with kernel vulnerabilities.
From: https://docs.docker.com/engine/security/security/
through https://security.stackexchange.com/questions/107850/docker-as-a-sandbox-for-untrusted-code
We can also sanitise input files to check this construnctions. In my project i created a whitelist of constructions that users can use. No dangerous constructions = no problem)
@denismaster could you go into a bit more detail about how you did that sanitization?
To do that properly your sanitizer would need a very deep understanding of Razor/C# syntax. Doesn't that mean you basically end up writing your own Razor interpreter (and still potentially leave many security loopholes open)??
@denismaster i'm also interested in this, can you please share more details?
I've enabled user to choose only one of predefined c# constructions, such as @Model, @foreach and @if. I'm using regex to find another language constructions things, and if there're any of them, the code will be stopped and request will be rejected. I do this before launching RazorLight.
Yes, this solution isn't the best, it can contains(and i think it contains) loopholes, but for me there is a good solution.
So far I could not find any options that would allow us to achieve exact code isolation as we could get running a separate AppDomain. Let this issue be opened till we find something decent to prevent running malicious code from non-trusted sources.
Thanks you @denismaster for sharing your ideas with us!
Hi, I just wanted to chip in that for use cases like email templates and other user driven templates there is the DotLiquid template engine which is exactly designed for doing this securely. This is why web frameworks like Giraffe offer a Razor engine for normal web pages and DotLiquid for user customizable templates.
@dustinmoris DotLiquid looks interesting. And even though it's not stated explicitly on their webpage, it seems to support .Net Core :)
Most helpful comment
I'm also interested in sanboxing capabilities using Dotnet core. I don't think running the untrusted code within containers is a great idea for various reasons, one of them being:
From: https://docs.docker.com/engine/security/security/
through https://security.stackexchange.com/questions/107850/docker-as-a-sandbox-for-untrusted-code