Mar 20, 2026·6 min read·28 visits
Scriban lacks default safe limits on string generation and object recursion. An attacker can use a simple loop within a template to generate gigabytes of string data in memory, causing an Out-of-Memory (OOM) crash.
The Scriban scripting engine is vulnerable to a Denial of Service (DoS) attack due to uncontrolled memory consumption. Attackers can execute specially crafted templates that trigger exponential string growth, leading to immediate heap memory exhaustion and process termination.
Scriban is a widely used text templating language and engine for the .NET framework, designed for parsing and rendering dynamic text blocks. Applications frequently integrate Scriban to allow users or administrators to define custom document layouts, email templates, or dynamic web content. The engine accepts template strings, compiles them into an Abstract Syntax Tree (AST), and evaluates them against a provided data context.
The vulnerability, identified as GHSA-5RPF-X9JG-8J5P, resides in the execution phase of the Scriban engine where resource constraints are not strictly enforced by default. The engine evaluates string concatenation operations within iterative structures (loops) without verifying the final memory footprint. This flaw is classified under CWE-400 (Uncontrolled Resource Consumption).
An attacker with the ability to supply or modify a Scriban template can exploit this behavior by constructing an exponential string growth payload. Upon evaluation, the .NET runtime will attempt to allocate continuous memory for the expanding string objects until the process exhausts all available heap memory. This results in an uncatchable OutOfMemoryException, causing the host application process to terminate abruptly and creating a severe Denial of Service condition.
The root cause of the vulnerability is the absence of secure-by-default resource limits within the Scriban TemplateContext and ParserOptions classes. Scriban exposes several configuration properties designed to prevent runaway execution, notably LimitToString, ExpressionDepthLimit, and ObjectRecursionLimit. However, in vulnerable versions, these properties initialize to values that impose no practical restrictions.
The LimitToString property dictates the maximum character count permitted for a string generated during template evaluation. By default, this property is set to 0, which the engine logic interprets as an unlimited length ceiling. Consequently, string operations are bounded only by the host operating system's available memory and the .NET runtime's internal string length limits.
Furthermore, .NET strings are immutable. Every concatenation operation creates a new string object in memory. When a string exceeds 85,000 bytes, the runtime allocates it on the Large Object Heap (LOH). Rapidly creating increasingly large string objects on the LOH causes severe memory fragmentation and forces frequent, expensive Garbage Collection (GC) cycles. The CPU overhead of the GC combined with the memory exhaustion accelerates the application crash.
The remediation effort introduced in commit a6fe6074199e5c04f4d29dc8d8e652b24d33e3e4 targets the default configuration values within the engine's core parsing and execution contexts. The patch modifies the constructors for ParserOptions and TemplateContext to establish baseline safety constraints.
// src/Scriban/Parsing/ParserOptions.cs - Patched
public ParserOptions()
{
ExpressionDepthLimit = 250; // Previously null
}The modification to ParserOptions successfully mitigates StackOverflow vectors during the AST generation phase by capping the maximum nesting depth of parsed expressions. Similarly, changes to TemplateContext introduce an ObjectRecursionLimit of 20, preventing memory exhaustion when rendering deep or circular object graphs.
However, analysis of the patched TemplateContext.cs reveals a critical residual risk. The LimitToString property remains initialized to 0.
// src/Scriban/TemplateContext.cs - Patched
public TemplateContext(ScriptObject builtin, IEqualityComparer<string> keyComparer)
{
// ...
LimitToString = 0; // Remains 0 (unlimited)
ObjectRecursionLimit = 20;
// ...
}Because LimitToString remains unbounded by default, the core exponential string growth vector is still viable unless the developer explicitly overrides this property during context instantiation. The patch addresses secondary exhaustion vectors but requires manual intervention to secure the primary string allocation vulnerability.
Exploitation requires the attacker to supply a template that executes an iterative string concatenation sequence. The default LoopLimit in Scriban is set to 1,000. An attacker only needs a fraction of this limit to exhaust process memory due to the nature of exponential growth.
The following proof-of-concept template demonstrates the attack vector:
{{ a = "a" }}
{{ for i in 1..30 }}
{{ a = a + a }}
{{ end }}The script initializes a variable a with a single character. The subsequent for loop executes 30 iterations. In each iteration, the variable a is concatenated with itself, doubling its length. The mathematical growth curve is $O(2^n)$.
After 10 iterations, the string length is 1,024 bytes. After 20 iterations, it reaches 1,048,576 bytes (~1MB). At the 30th iteration, the string length attempts to reach 1,073,741,824 bytes (~1GB). The memory allocation requests scale so rapidly that the host application will crash with an OutOfMemoryException long before reaching the 1,000-iteration default loop limit.
The impact of this vulnerability is limited strictly to Availability. Exploitation does not permit remote code execution, nor does it provide the attacker with access to unauthorized data. However, the resulting Denial of Service is absolute and requires zero authentication if the application exposes template rendering to anonymous users.
When the .NET runtime encounters an OOM condition caused by heap exhaustion, it terminates the host process. In modern microservice architectures, an orchestration platform (like Kubernetes) will detect the crashed container and attempt to restart it. If the attacker automates the payload delivery, they can create a continuous crash-loop condition, permanently disabling the targeted service.
Applications that evaluate templates on background worker threads are particularly at risk. An unhandled OutOfMemoryException on a background thread will tear down the entire application domain, impacting all active user sessions and terminating in-flight transactions. The CVSS vector for this vulnerability reflects a High severity score due to the low complexity of the attack and the severe impact on system availability.
The primary remediation step is to update the Scriban NuGet package to version 5.12.1, 6.5.7, or later. These versions include the default limits for expression depth and object recursion. However, upgrading the package alone is insufficient to fully protect against the string growth vector.
Developers must explicitly enforce safe resource limits when instantiating the TemplateContext object. Setting a strict upper bound on string allocation ensures the engine halts execution before memory exhaustion occurs.
var context = new TemplateContext();
// Restrict string generation to a maximum of 1MB
context.LimitToString = 1048576;
// Restrict loop iterations to a safe threshold
context.LoopLimit = 100;
// Ensure recursive limit is maintained
context.ObjectRecursionLimit = 20;In scenarios where arbitrary users supply templates, input validation is a necessary defense-in-depth measure. Applications should parse the submitted template into an AST and inspect it for iterative concatenation patterns before passing it to the evaluation engine. Any template containing loop constructs that modify variables used in their own condition or body should be flagged and rejected.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Scriban Scriban | < 5.12.1 | 5.12.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.5 |
| Impact | Denial of Service (DoS) |
| Exploit Status | Proof of Concept Available |
| Authentication Required | None |
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.
CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.
An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.
An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.
CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.
An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.
A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.