csharp.dotnet.security.razor-template-injection.razor-template-injection

profile photo of semgrepsemgrep
Author
unknown
Download Count*

User-controllable string passed to Razor.Parse. This leads directly to code execution in the context of the process.

Run Locally

Run in CI

Defintion

rules:
  - id: razor-template-injection
    message: User-controllable string passed to Razor.Parse. This leads directly to
      code execution in the context of the process.
    severity: WARNING
    metadata:
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      category: security
      cwe:
        - "CWE-94: Improper Control of Generation of Code ('Code Injection')"
      cwe2022-top25: true
      owasp:
        - A03:2021 - Injection
      references:
        - https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/
      subcategory:
        - vuln
      technology:
        - .net
        - razor
        - asp
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    languages:
      - csharp
    mode: taint
    pattern-sources:
      - patterns:
          - focus-metavariable: $ARG
          - pattern-inside: |
              public ActionResult $METHOD(..., string $ARG,...){...}
    pattern-sinks:
      - pattern: |
          Razor.Parse(...)
    pattern-sanitizers:
      - not_conflicting: true
        pattern: $F(...)

Examples

razor-template-injection.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using RazorEngine;
using RazorEngine.Templating;

    namespace RazorVulnerableApp.Controllers
{
    public class HomeController : Controller
    {
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Index(string inert, string razorTpl)
        {
            // WARNING This code is vulnerable on purpose: do not use in production and do not take it as an example!
            // ruleid: razor-template-injection
            ViewBag.RenderedTemplate = Razor.Parse(razorTpl);
            ViewBag.Template = razorTpl;
            return View();
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Index(string inter, string razorTpl)
        {
            var junk = someFunction(razorTpl);
            // WARNING This code is vulnerable on purpose: do not use in production and do not take it as an example!
            // ok: razor-template-injection
            ViewBag.RenderedTemplate = Razor.Parse(junk);
            ViewBag.Template = razorTpl;
            return View();
        }
    }
}