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-M2P3-HWV5-XPQW
6.5

GHSA-M2P3-HWV5-XPQW: Denial of Service via Unbounded Cumulative Template Output in Scriban

Alon Barad
Alon Barad
Software Engineer

Mar 25, 2026·5 min read·3 visits

PoC Available

Executive Summary (TL;DR)

Scriban versions prior to 7.0.0 fail to cumulatively track string allocations across template loops. Attackers can leverage this bypass to allocate gigabytes of memory using default settings, crashing the host .NET application.

The Scriban template engine for .NET contains a flaw in its memory allocation limiting logic. An attacker who can supply malicious templates can bypass the `LimitToString` safety mechanism, causing the engine to allocate excessive memory. This leads to an Out-of-Memory (OOM) condition and subsequent application crash, resulting in a Denial of Service (DoS).

Vulnerability Overview

Scriban is a popular text templating engine and parser designed for the .NET framework. It is frequently integrated into applications that require dynamic content generation, such as email templating services, static site generators, and web applications. When processing untrusted user input, templating engines must strictly control resource consumption to prevent abuse.

Vulnerability GHSA-M2P3-HWV5-XPQW identifies a flaw in Scriban's resource limitation controls, specifically categorized under CWE-770 (Allocation of Resources Without Limits or Throttling). The vulnerability allows an attacker to construct a specialized template that systematically bypasses the engine's built-in string allocation limits. This bypass results in unbounded memory consumption during the template evaluation and rendering phases.

All versions of the Scriban NuGet package prior to version 7.0.0 are vulnerable to this issue. Exploitation requires the target application to accept and evaluate templates provided by an attacker. A successful attack consumes the host system's available memory, predictably resulting in a Denial of Service (DoS) for the entire application environment.

Root Cause Analysis

The Scriban engine implements a safety setting named LimitToString to prevent excessive memory allocation during string conversion and generation. Since commit b5ac4bf, this limit has defaulted to 1,048,576 bytes (1MB). The vulnerability exists because this specific safety check was enforced on a per-expression basis rather than cumulatively across the entire template execution lifecycle.

Internally, the engine tracks the size of the current string being constructed using the _currentToStringLength variable. When a top-level string conversion operation completes, the engine evaluates the condition _objectToStringLevel == 0. When this condition evaluates to true, the engine resets the _currentToStringLength counter back to zero, erasing the record of previous allocations.

This counter reset behavior introduces a logical flaw when combined with template loop constructs. An attacker can define a loop where each individual iteration generates a distinct string that remains just under the 1MB threshold. Because the tracking counter resets after each expression evaluates, the engine never triggers the LimitToString violation exception, allowing aggregate memory allocations to grow unboundedly.

Exploitation and Proof of Concept

Exploiting this vulnerability relies on combining the per-expression limit bypass with Scriban's default loop iteration limits. By default, Scriban enforces a LoopLimit of 1,000 iterations to prevent infinite loops. An attacker can construct a payload that maximizes memory allocation within these default boundaries without triggering any exceptions.

The following Proof of Concept (PoC) demonstrates the attack using standard TemplateContext settings. The payload instructs the engine to iterate 1,000 times. During each iteration, the engine performs string multiplication to generate a string of 1,048,575 characters (assuming single-byte characters, this equals 1,048,575 bytes).

using Scriban;
 
// This payload relies on default TemplateContext settings:
// LoopLimit = 1000
// LimitToString = 1,048,576 (1MB)
var template = Template.Parse(@"{{ for i in 1..1000 }}{{ 'a' * 1048575 }}{{ end }}");
 
// Each iteration generates a string of 1,048,575 bytes.
// 1,048,575 < 1,048,576 (passes the LimitToString check).
// Total allocation = 1,000 * 1,048,575 bytes ≈ 1GB.
template.Render(); 

Because 1,048,575 bytes is strictly less than the 1,048,576-byte LimitToString threshold, the per-expression check passes. The engine then resets the tracking counter. Across 1,000 iterations, the application allocates approximately 1 gigabyte of memory in rapid succession. In environments with concurrency, multiple identical requests will quickly exhaust system memory.

Impact Assessment

The primary impact of this vulnerability is a high-severity Denial of Service (DoS) affecting the availability of the host application. In the .NET runtime environment, an unhandled OutOfMemoryException typically cannot be caught and safely recovered from using standard exception handling mechanisms. When the runtime fails to allocate requested memory, it terminates the hosting process entirely.

Process termination affects all users currently interacting with the application, not just the attacker executing the malicious payload. Any active transactions, background processing tasks, or in-memory state will be lost when the process terminates. If the application runs within a containerized environment (such as Docker or Kubernetes) with strict memory quotas, the orchestrator will forcibly kill the container via an OOMKilled signal.

Depending on the application architecture, the required privileges for exploitation range from Low to None. If the application exposes template generation features to unauthenticated users over a network, an attacker can trigger the OOM condition remotely with a single HTTP request. There is no impact on confidentiality or integrity, as the vulnerability does not expose sensitive data or allow arbitrary code execution.

Remediation and Mitigation

The vendor addressed this vulnerability in Scriban version 7.0.0. The patch modifies the memory tracking logic to enforce cumulative string allocation limits across the entire template execution context, rather than on a per-expression basis. Developers must upgrade all vulnerable Scriban package references to version 7.0.0 or later to ensure complete protection.

For environments where immediate patching is not technically feasible, developers can implement manual mitigations by explicitly restricting the TemplateContext settings. Administrators should instantiate the TemplateContext and explicitly set both LimitToString and LoopLimit to highly restrictive values tailored to the specific operational requirements of the application. This reduces the maximum possible memory allocation a single template execution can trigger.

As a defense-in-depth measure, security teams should implement resource quotas at the infrastructure level. Configuring memory limits via cgroups in Linux, container memory limits in Docker, or App Service plans in Azure ensures that an OOM condition within the application process does not compromise the underlying host or other co-located services.

Official Patches

ScribanScriban 7.0.0 Release Notes

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

Scriban .NET Template Engine

Affected Versions Detail

Product
Affected Versions
Fixed Version
Scriban
Scriban
< 7.0.07.0.0
AttributeDetail
CWE IDCWE-770
Attack VectorNetwork
ImpactDenial of Service (DoS)
CVSS v3.16.5 (Moderate)
Exploit StatusPoC Available
Privileges RequiredLow / None

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

Allocation of Resources Without Limits or Throttling

References & Sources

  • [1]GitHub Advisory GHSA-M2P3-HWV5-XPQW
  • [2]Scriban GitHub Repository
  • [3]Scriban 7.0.0 Release Notes

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.