Remote code execution (RCE) via user input in Razor.Parse

High Risk cross-site-scripting
csharpdotnetrazortemplate-injectionrceweb

What it is

Remote code execution vulnerability in .NET applications where user-controlled template strings are passed to Razor.Parse, which compiles and executes template expressions, enabling server-side template injection and arbitrary code execution on the server.

using RazorEngine;
using RazorEngine.Templating;
using Microsoft.AspNetCore.Mvc;

public class TemplateController : Controller
{
    [HttpPost]
    public IActionResult ProcessTemplate(string template, object model)
    {
        // VULNERABLE: User input passed to Razor.Parse
        var result = Engine.Razor.RunCompile(
            template, "templateKey", null, model);
        
        return Content(result, "text/html");
    }
}

// Attack payload:
// @{System.Diagnostics.Process.Start("calc.exe");}
// @{var x = System.IO.File.ReadAllText("/etc/passwd");}
// <p>@x</p>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using System.Collections.Generic;
using System.Threading.Tasks;

public class SecureTemplateController : Controller
{
    private readonly ICompositeViewEngine _viewEngine;
    
    // Allowed template mapping
    private readonly Dictionary<string, string> _templateMap = new()
    {
        { "email", "Templates/Email" },
        { "notification", "Templates/Notification" },
        { "report", "Templates/Report" }
    };
    
    public SecureTemplateController(ICompositeViewEngine viewEngine)
    {
        _viewEngine = viewEngine;
    }
    
    [HttpPost]
    public IActionResult ProcessTemplate(string templateType, object model)
    {
        // SECURE: Validate against allowlist
        if (!_templateMap.ContainsKey(templateType))
        {
            return BadRequest("Invalid template type");
        }
        
        // Use precompiled template with safe model binding
        return View(_templateMap[templateType], model);
    }
}

💡 Why This Fix Works

The vulnerable code passes user-controlled template strings directly to Razor.Parse, which compiles and executes arbitrary C# code embedded in the template. The secure version uses a whitelist of predefined, precompiled Razor views and only allows selecting from approved templates, preventing template injection attacks.

Why it happens

User input is directly passed to Razor.Parse without validation or sanitization.

Root causes

User-Controlled Template Strings

User input is directly passed to Razor.Parse without validation or sanitization.

Server-Side Template Compilation

Razor.Parse compiles and executes template expressions at runtime, enabling code injection.

Fixes

1

Use Precompiled Razor Views

Use only trusted, precompiled Razor views instead of parsing user-supplied template strings.

2

Implement Safe Template Placeholders

Use a safe, non-executable template engine with strict placeholder replacement for user customization.

3

Implement Whitelist-Based Validation

If dynamic templating is required, use strict validation with a whitelist of allowed template constructs.

Detect This Vulnerability in Your Code

Sourcery automatically identifies remote code execution (rce) via user input in razor.parse and many other security issues in your codebase.