CVE-2026-74784
Scriban before 7.2.0 Denial of Service via array.insert_at
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
Scriban before 7.2.0 Denial of Service via array.insert_at
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
- Record
CVE-2026-74784- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-59950
8.7
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
- Record
EUVD-2026-59950- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-24c8-4792-22hx
8.7
Scriban: array.insert_at index parameter DoS bypasses LoopLimit and LimitToString
Summary
ArrayFunctions.InsertAt in Scriban allocates index - list.Count null entries in a tight C# for loop with no bound on index. The function is exposed to template authors as array.insert_at, and the fill loop ignores every existing safety control: LoopLimit, LimitToString, ObjectRecursionLimit, and RecursiveLimit. A single template such as {{ [1] | array.insert_at 200000000 'x' | array.size }} causes OutOfMemoryException in well under a second on a host with 1 GB of memory, even when LoopLimit is set to 10 and LimitToString is set to 100. Because OutOfMemoryException is generally not caught by the template renderer or by typical host applications, the vulnerability terminates the host process, not just the template.
This is a sibling vector to GHSA-xw6w-9jjh-p9cr / GHSA-c875-h985-hvrc / GHSA-v66j-x4hw-fv9g, which patched comparable unbounded primitives in string * int, array.size, array.join, string.pad_left, and string.pad_right. The 7.0.0 hardening pass (dde661d "Apply LoopLimit to internal iteration paths" and 4227fde "Harden string padding width limits") swept the equivalent loops in ArrayFunctions and StringFunctions but missed InsertAt.
Details
Reproducible in 7.1.0 (latest tag) and on master at c8094b0.
src/Scriban/Functions/ArrayFunctions.cs:369-386:
public static IEnumerable InsertAt(IEnumerable? list, int index, object? value)
{
if (index < 0)
{
index = 0;
}
var array = list is null ? new ScriptArray() : new ScriptArray(list);
// Make sure that the list has already inserted elements before the index
for (int i = array.Count; i < index; i++)
{
array.Add(null); // <-- unbounded fill, no StepLoop, no Limit*
}
array.Insert(index, value);
return array;
}
The function is registered as the template builtin array.insert_at (array.fmt-cs and the standard ArrayFunctions ScriptObject reflection registration). It is invoked from a template like [1] | array.insert_at 999999999 "x".
Three properties combine to make this exploitable:
-
There is no context-aware overload. Comparable amplification primitives in this same file received a
(TemplateContext, SourceSpan, ...)overload that callsStepLoopper iteration (AddRange,Compact,Concat,Last,Limit,Offset,Reverse,Size,Sort,Uniq,Contains,Each,Filter,Join,Map,Any-- see commitdde661d).InsertAtwas not given that treatment. The singleIEnumerable, int, objectsignature is what the engine resolves to, so no host configuration changes its behaviour. -
The loop itself never consults
context.LoopLimit,context.LimitToString,context.RecursiveLimit, orcontext.ObjectRecursionLimit. There is no upstream call intocontext.StepLoop,context.CheckAbort, or any guard. Withindex = 200_000_000, the C# loop callsScriptArray.Add(null)200 million times on aList<object>whose capacity doubles geometrically; the JIT-compiled tight loop reaches the .NET array allocator faster than the GC can keep up. -
OutOfMemoryExceptionis the actual failure mode. Per Microsoft,OutOfMemoryExceptionand friends are not reliably catchable by user code in production CLR runtimes; even when they are caught, large background allocations and triggered GC cycles leave the process in a degraded state. In the PoC below, the renderer wraps the OOM in aScriptRuntimeExceptionbecause the underlying allocation lands inside the renderer's try block, but on hosts that allocate the array slightly differently (e.g. tighter memory cap, server GC, or higher index value than the host has memory for) the bareOutOfMemoryExceptionpropagates and crashes the AppDomain.
The pattern that matches the existing fixes is to add a context-aware overload that validates index against LoopLimit (or LimitToString for the resulting array footprint) before the fill loop runs, and to…
- Record
GHSA-24c8-4792-22hx- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-770
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-wcrg-p6mv-jx2j
8.7
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function...
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
- Record
GHSA-wcrg-p6mv-jx2j- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-770
- Updated
- 2026-11-02
NVD
8.7
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
- Record
CVE-2026-74784- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-770
- Updated
- 2026-11-02
OSV
8.7
Scriban before 7.2.0 Denial of Service via array.insert_at
Scriban before 7.2.0 contains a denial of service vulnerability in the array.insert_at function that allocates unbounded null entries without respecting LoopLimit or LimitToString constraints. Attackers can supply a large index parameter to trigger OutOfMemoryException and crash the host process in under a second.
- Record
CVE-2026-74784- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVGHSA-24c8-4792-22hx
8.7
Scriban: array.insert_at index parameter DoS bypasses LoopLimit and LimitToString
Summary
ArrayFunctions.InsertAt in Scriban allocates index - list.Count null entries in a tight C# for loop with no bound on index. The function is exposed to template authors as array.insert_at, and the fill loop ignores every existing safety control: LoopLimit, LimitToString, ObjectRecursionLimit, and RecursiveLimit. A single template such as {{ [1] | array.insert_at 200000000 'x' | array.size }} causes OutOfMemoryException in well under a second on a host with 1 GB of memory, even when LoopLimit is set to 10 and LimitToString is set to 100. Because OutOfMemoryException is generally not caught by the template renderer or by typical host applications, the vulnerability terminates the host process, not just the template.
This is a sibling vector to GHSA-xw6w-9jjh-p9cr / GHSA-c875-h985-hvrc / GHSA-v66j-x4hw-fv9g, which patched comparable unbounded primitives in string * int, array.size, array.join, string.pad_left, and string.pad_right. The 7.0.0 hardening pass (dde661d "Apply LoopLimit to internal iteration paths" and 4227fde "Harden string padding width limits") swept the equivalent loops in ArrayFunctions and StringFunctions but missed InsertAt.
Details
Reproducible in 7.1.0 (latest tag) and on master at c8094b0.
src/Scriban/Functions/ArrayFunctions.cs:369-386:
public static IEnumerable InsertAt(IEnumerable? list, int index, object? value)
{
if (index < 0)
{
index = 0;
}
var array = list is null ? new ScriptArray() : new ScriptArray(list);
// Make sure that the list has already inserted elements before the index
for (int i = array.Count; i < index; i++)
{
array.Add(null); // <-- unbounded fill, no StepLoop, no Limit*
}
array.Insert(index, value);
return array;
}
The function is registered as the template builtin array.insert_at (array.fmt-cs and the standard ArrayFunctions ScriptObject reflection registration). It is invoked from a template like [1] | array.insert_at 999999999 "x".
Three properties combine to make this exploitable:
-
There is no context-aware overload. Comparable amplification primitives in this same file received a
(TemplateContext, SourceSpan, ...)overload that callsStepLoopper iteration (AddRange,Compact,Concat,Last,Limit,Offset,Reverse,Size,Sort,Uniq,Contains,Each,Filter,Join,Map,Any-- see commitdde661d).InsertAtwas not given that treatment. The singleIEnumerable, int, objectsignature is what the engine resolves to, so no host configuration changes its behaviour. -
The loop itself never consults
context.LoopLimit,context.LimitToString,context.RecursiveLimit, orcontext.ObjectRecursionLimit. There is no upstream call intocontext.StepLoop,context.CheckAbort, or any guard. Withindex = 200_000_000, the C# loop callsScriptArray.Add(null)200 million times on aList<object>whose capacity doubles geometrically; the JIT-compiled tight loop reaches the .NET array allocator faster than the GC can keep up. -
OutOfMemoryExceptionis the actual failure mode. Per Microsoft,OutOfMemoryExceptionand friends are not reliably catchable by user code in production CLR runtimes; even when they are caught, large background allocations and triggered GC cycles leave the process in a degraded state. In the PoC below, the renderer wraps the OOM in aScriptRuntimeExceptionbecause the underlying allocation lands inside the renderer's try block, but on hosts that allocate the array slightly differently (e.g. tighter memory cap, server GC, or higher index value than the host has memory for) the bareOutOfMemoryExceptionpropagates and crashes the AppDomain.
The pattern that matches the existing fixes is to add a context-aware overload that validates index against LoopLimit (or LimitToString for the resulting array footprint) before the fill loop runs, and to…
- Record
GHSA-24c8-4792-22hx- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-770
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
scribanNuGet |
through 7.1.0 | 7.2.0 |
Scriban.SignedNuGet |
through 7.1.0 | 7.2.0 |
scribanNuGet |
before 7.2.0, plus listed versions 0.1.00.10.00.11.00.12.00.12.1 Show 45 moreShow less0.13.00.14.00.15.00.16.00.2.00.2.10.2.20.3.00.3.10.3.1-pre0280.4.00.5.00.6.00.7.00.9.00.9.0-pre1000.9.11.0.01.0.0-beta-0011.0.0-beta-0021.0.0-beta-0031.0.0-beta-0041.0.0-beta-0051.0.0-beta-0061.1.01.1.11.2.01.2.11.2.21.2.31.2.41.2.51.2.61.2.71.2.81.2.92.0.02.0.0-alpha-0012.0.0-alpha-0022.0.0-alpha-0032.0.0-alpha-0042.0.0-alpha-0052.0.0-alpha-0062.0.12.1.0 |
7.2.0 |
Scriban.SignedNuGet |
before 7.2.0, plus listed versions 0.10.00.11.00.12.00.12.10.13.0 Show 45 moreShow less0.14.00.15.00.16.00.9.00.9.11.0.01.0.0-beta-0011.0.0-beta-0021.0.0-beta-0031.0.0-beta-0041.0.0-beta-0051.0.0-beta-0061.1.01.1.11.2.01.2.11.2.21.2.31.2.41.2.51.2.61.2.71.2.81.2.92.0.02.0.0-alpha-0012.0.0-alpha-0022.0.0-alpha-0032.0.0-alpha-0042.0.0-alpha-0052.0.0-alpha-0062.0.12.1.02.1.12.1.22.1.32.1.43.0.03.0.13.0.23.0.33.0.43.0.53.0.63.0.7 |
7.2.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-74784 is a high vulnerability (CVSS 8.7) in Scriban, published May 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.45%, the 38th percentile. Fixed in scriban 7.2.0.
References
github.com/scriban/scriban/security/advisories/GHSA-24c8-4792-22hx
vulncheck.com/advisories/scriban-before-denial-of-service-via-array-insert-at
github.com/advisories/GHSA-24c8-4792-22hx
nvd.nist.gov/vuln/detail/CVE-2026-74784
github.com/advisories/GHSA-wcrg-p6mv-jx2j
github.com/CVEProject/cvelistV5/tree/main/cves/2026/74xxx/CVE-2026-74784.json
github.com/scriban/scriban
Left out here: 150 versions and the rest of 2 source descriptions. The JSON record has them.