CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-XW6W-9JJH-P9CR
6.5

GHSA-XW6W-9JJH-P9CR: Multiple Denial-of-Service Vulnerabilities in Scriban Templating Engine

Alon Barad
Alon Barad
Software Engineer

Mar 25, 2026·7 min read·4 visits

PoC Available

Executive Summary (TL;DR)

Scriban versions before 7.0.0 are vulnerable to Denial of Service via unbounded resource consumption. Unauthenticated or low-privileged users can crash the host application by providing crafted template expressions that bypass configured string length and loop limits.

The Scriban .NET templating engine versions prior to 7.0.0 contain three distinct denial-of-service vulnerabilities. These flaws arise from improper enforcement of resource limits during expression evaluation, specifically concerning string multiplication, bitwise shifts, and range enumerations. An attacker with template authoring privileges can exploit these vectors to trigger OutOfMemoryException or CPU exhaustion, resulting in abrupt application termination or degraded performance.

Vulnerability Overview

Scriban is a fast, powerful, and safe templating language and engine for .NET, frequently utilized in content management systems, static site generators, and email marketing platforms. The engine exposes a configuration object, TemplateContext, which administrators use to enforce execution limits. These boundaries include LimitToString for string allocations and LoopLimit for maximum iteration counts.

Versions of Scriban prior to 7.0.0 fail to enforce these safety controls across three specific expression evaluation paths. The application trusts the constraints established in TemplateContext but contains implementation flaws that allow certain operations to bypass these checks entirely. This results in unrestricted resource allocation and processing.

An attacker who can supply or modify template content can exploit these paths to cause a Denial of Service (DoS). The vulnerabilities are classified under CWE-400 (Uncontrolled Resource Consumption), CWE-770 (Allocation of Resources Without Limits or Throttling), and CWE-834 (Excessive Iteration). The impact varies depending on the targeted vector but culminates in either process termination or complete thread pool exhaustion.

The attack vector requires no elevated privileges beyond the ability to submit template data. Applications that parse user-provided strings via Template.Parse() without pre-processing validation are inherently vulnerable. The severity is constrained to a 6.5 Medium rating due to the requirement of application-specific template input mechanisms and the lack of confidentiality or integrity impacts.

Root Cause Analysis

The first vulnerability vector exists within ScriptBinaryExpression.cs handling the string multiplication operator (string * int). The CalculateToString method attempts to replicate the input string a specified number of times using a standard for loop and a StringBuilder. The implementation lacks a pre-allocation check against context.LimitToString, allowing the StringBuilder to grow until the .NET runtime throws an OutOfMemoryException.

The second vector involves the ShiftLeft operator (<<), implemented in CalculateLongWithInt and CalculateBigIntegerNoFit. Unlike the exponentiation operator (Power), which uses BigInteger.ModPow and enforces a MaxBigInteger boundary, the left-shift operation applies no such limits. Shifting a BigInteger by an extremely large integer value forces the .NET runtime to allocate a backing array large enough to hold the shifted bits, again leading to an immediate OutOfMemoryException.

The third vector exploits range operators (.. and ..<) used in conjunction with built-in array functions. Range operators in Scriban return lazy IEnumerable<object> iterators. When these ranges are passed directly to functions like array.size or array.join, the underlying implementation fully enumerates the iterator. Because this enumeration happens inside the native function rather than the template engine's main execution loop, it never invokes context.StepLoop(). Consequently, the enumeration entirely bypasses the context.LoopLimit protection, causing CPU exhaustion.

Code Analysis

The flaw in the string multiplication implementation is located between lines 319 and 334 in src/Scriban/Syntax/Expressions/ScriptBinaryExpression.cs. The vulnerable code executes a loop based strictly on user-supplied values without boundary verification.

var leftText = context.ObjectToString(left);
var builder = new StringBuilder();
for (int i = 0; i < value; i++)
{
    builder.Append(leftText);
}
return builder.ToString();

The fundamental issue here is that context.LimitToString (which defaults to 1MB) is ignored. The patch resolves this by introducing a mathematical boundary check prior to the loop execution. By calculating the expected final size (long)value * leftText.Length, the engine can throw a controlled ScriptRuntimeException before any substantial memory allocation occurs.

// Patched logic
if (context.LimitToString > 0 && (long)value * leftText.Length > context.LimitToString)
{
    throw new ScriptRuntimeException(span, "String multiplication would exceed LimitToString");
}

The fix for the loop limit bypass requires the engine to track iteration counts within the built-in functions that consume IEnumerable<object>. The patched RangeInclude and RangeExclude structures are updated to increment and verify against context.LoopLimit during every iteration step. This ensures that a range calculation like (0..1000000000) halts after reaching the threshold.

Exploitation and Proof of Concept

Exploitation relies on passing a single crafted expression into the Template.Parse() method and subsequently calling template.Render(context). The attacker does not need to understand the underlying architecture, only that Scriban is processing the input.

To trigger the string multiplication Out of Memory (OOM) condition, the attacker supplies a template that multiplies a small string by an exceptionally large integer. The code below demonstrates this attack. The default LimitToString configuration of 1,048,576 bytes fails to prevent the approximately 2GB allocation attempt.

var template = Template.Parse("{{ 'AAAA' * 500000000 }}");
var context = new TemplateContext();
template.Render(context); // Throws OutOfMemoryException

For the bitwise shift OOM, the attacker leverages the << operator. The resulting BigInteger allocation bypasses normal numerical limits. The following snippet forces the application to allocate a BigInteger containing 100 million bits (approximately 12.5MB per evaluation, easily scaled by the attacker to exhaust available memory).

var template = Template.Parse("{{ 1 << 100000000 }}");
var context = new TemplateContext();
template.Render(context); // Throws OutOfMemoryException

The CPU exhaustion vector targets the loop limit bypass. By piping an enormous range into the array.size built-in function, the application attempts to enumerate 1 billion items synchronously. This blocks the executing thread indefinitely, starving the application's thread pool and resulting in a denial of service.

var template = Template.Parse("{{ (0..1000000000) | array.size }}");
var context = new TemplateContext();
template.Render(context); // High CPU utilization, hangs execution

Impact Assessment

The primary consequence of this vulnerability is a complete Denial of Service. In the context of .NET runtime environments, an OutOfMemoryException is typically a fatal error. Modern .NET runtimes generally terminate the process entirely when an OOM exception is thrown by the execution engine, rather than allowing the application to catch and recover from the error.

Process termination affects all users currently interacting with the host application. If the application handles web requests, all active connections are dropped. In environments orchestrated by container managers (e.g., Kubernetes), this leads to continuous pod restarts (CrashLoopBackOff) if the attacker automates the malicious request.

The CPU exhaustion vector introduces a secondary impact model. While it may not crash the process immediately, it ties up application threads. If an attacker submits multiple requests utilizing the loop bypass vector, the .NET thread pool becomes starved. Subsequent legitimate requests will queue and eventually time out, effectively rendering the application unresponsive.

Remediation and Defensive Strategies

The definitive mitigation for this vulnerability is upgrading the Scriban NuGet package to version 7.0.0 or later. This release introduces comprehensive boundary checks in the abstract syntax tree evaluation logic, explicitly capping string operations, bitwise shifts, and range iterators to the limits defined in TemplateContext.

If immediate patching is not technically feasible, development teams must implement input validation workarounds. The most robust temporary measure involves restricting template authoring capabilities strictly to highly trusted administrators. In multi-tenant environments where user-supplied templates are a core feature, restricting access may not be an option.

In cases where untrusted input must be processed by vulnerable versions, implement a strict pre-compilation regex filter. The filter should scan the template string and reject inputs containing multiplication operators (*), left shift operators (<<), and range operators (.. and ..<). This degrades the functionality of the templating engine but neutralizes the known attack vectors.

Official Patches

ScribanNuGet Package Version 7.0.0 containing the fix.

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

Affected Systems

Applications utilizing the Scriban templating engine (NuGet package: Scriban)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Scriban
Alexandre Mutel
>= 0.1.0, < 7.0.07.0.0
AttributeDetail
Vulnerability TypeDenial of Service (DoS)
CWE IDCWE-400, CWE-770, CWE-834
CVSS v3.1 Score6.5 Medium
Attack VectorNetwork (Remote)
Privileges RequiredLow
User InteractionNone
Exploit StatusProof of Concept available

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.

Known Exploits & Detection

GitHub AdvisoryProof of Concept demonstrating the three resource exhaustion vectors.

Vulnerability Timeline

Advisory GHSA-XW6W-9JJH-P9CR Published
2026-03-24

References & Sources

  • [1]GitHub Advisory GHSA-xw6w-9jjh-p9cr
  • [2]Scriban Repository
  • [3]Scriban 7.0.0 Release on NuGet

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.