Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
14 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
The ExpressionDepthLimit parser guard in Scriban does not actually stop parsing — it only logs a non-fatal error and lets recursive descent continue. As a result, a template containing a deeply nested expression (parentheses, array initializers, object initializers, or unary operators) drives the recursive-descent parser into a native stack overflow. The resulting StackOverflowException is uncatchable in .NET and immediately terminates the host process. Any application that parses an attacker-influenced template — or that passes attacker-controlled strings to object.eval / object.evaltemplate — can be crashed by a single small request (roughly an 8 KB payload). This is a denial-of-service. It affects both Scriban-native (Template.Parse) and Liquid (Template.ParseLiquid) syntax modes, which share the same expression parser. This re-opens two advisories that were reported as fixed: GHSA-wgh7-7m3c-fx25 ("Uncontrolled recursion in parser → StackOverflow", reported fixed in 6.6.0)…
Recommended action: Upgrade to 7.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The array multiplication operator (array integer) in Scriban allocates a result whose size is the product of the attacker-controlled integer and the array length, with no LoopLimit / LimitToString check and no overflow-safe arithmetic. A ~40-byte template forces a multi-gigabyte allocation, producing a denial-of-service. This is the unguarded sibling of operations that were hardened against the same class of abuse: string integer (gated by a LimitToString pre-check), array.insertat (gated by StepLoop/LoopLimit — the GHSA-24c8-4792-22hx fix shipped in 7.2.0, scored 8.7 High), and the range/iteration paths covered by GHSA-c875-h985-hvrc ("Built-in operations bypass LoopLimit", fixed 7.0.0). The same LoopLimit-based hardening pattern was applied to those operations but never to array integer. This can be observed directly in 7.0.0, the release where GHSA-c875 was patched: (1..5) 50000000 (and 1..N | array.size) correctly throws Exceeding number of iteration limit '1000', while…
Recommended action: Upgrade to 7.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
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.insertat, and the fill loop ignores every existing safety control: LoopLimit, LimitToString, ObjectRecursionLimit, and RecursiveLimit. A single template such as {{ [1] | array.insertat 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.padleft, and string.padright. The 7.0.0 hardening pass (dde661d "Apply LoopLimit to…
Recommended action: Upgrade to 7.2.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Scriban's expression evaluation contains three distinct code paths that allow an attacker who can supply a template to cause denial of service through unbounded memory allocation or CPU exhaustion. The existing safety controls (LimitToString, LoopLimit) do not protect these paths, giving applications a false sense of safety when evaluating untrusted templates. Details Vector 1: Unbounded string multiplication In ScriptBinaryExpression.cs, the CalculateToString method handles the string int operator by looping without any upper bound: The LimitToString safety control (default 1MB) does not protect this code path. It only applies to ObjectToString output conversions in TemplateContext.Helpers.cs (lines 101-121), not to intermediate string values constructed inside CalculateToString. The LoopLimit also does not apply because this is a C for loop, not a template-level loop — StepLoop() is never called here. Vector 2: Unbounded BigInteger shift left The CalculateLongWithInt and…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The LimitToString safety limit (default 1MB since commit b5ac4bf) can be bypassed to allocate approximately 1GB of memory by exploiting the per-call reset of currentToStringLength in ObjectToString. Each template expression rendered through TemplateContext.Write(SourceSpan, object) triggers a separate top-level ObjectToString call that resets the length counter to zero, and the underlying StringBuilderOutput has no cumulative output size limit. An attacker who can supply a template can cause an out-of-memory condition in the host application. Details The root cause is in TemplateContext.Helpers.cs, in the ObjectToString method: Each time a template expression is rendered, TemplateContext.Write(SourceSpan, object) calls ObjectToString: The StringBuilderOutput.Write method appends unconditionally with no size check: Execution flow: 1. Template creates a string of length 1,048,575 (one byte under the 1MB LimitToString default) 2. A for loop iterates up to LoopLimit (default…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The object.tojson builtin function in Scriban performs recursive JSON serialization via an internal WriteValue() static local function that has no depth limit, no circular reference detection, and no stack overflow guard. A Scriban template containing a self-referencing object passed to object.tojson triggers unbounded recursion, causing a StackOverflowException that terminates the hosting .NET process. This is a fatal, unrecoverable crash — StackOverflowException cannot be caught by user code in .NET. Details The vulnerable code is the WriteValue() static local function at src/Scriban/Functions/ObjectFunctions.cs:494: This function has none of the safety mechanisms present in other recursive paths: - ObjectToString() at TemplateContext.Helpers.cs:98 checks ObjectRecursionLimit (default 20) - EnterRecursive() at TemplateContext.cs:957 calls RuntimeHelpers.EnsureSufficientExecutionStack() - CheckAbort() at TemplateContext.cs:464 also calls EnsureSufficientExecutionStack() The…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The built-in string.padleft and string.padright template functions in Scriban perform no validation on the width parameter, allowing a template expression to allocate arbitrarily large strings in a single call. When Scriban is exposed to untrusted template input — as in the official Scriban.AppService playground deployed on Azure — an unauthenticated attacker can trigger ~1GB memory allocations with a 39-byte payload, crashing the service via OutOfMemoryException. Details StringFunctions.PadLeft and StringFunctions.PadRight (src/Scriban/Functions/StringFunctions.cs:1181-1203) directly delegate to .NET's String.PadLeft(int) / String.PadRight(int) with no bounds checking: The TemplateContext.LimitToString property (default 1MB, set at TemplateContext.cs:147) does not prevent the allocation. This limit is only checked during ObjectToString() conversion (TemplateContext.Helpers.cs:101-103), which runs after the string has been fully allocated by PadLeft/PadRight. The dangerous…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Scriban's LoopLimit only applies to script loop statements, not to expensive iteration performed inside operators and builtins. An attacker can submit a single expression such as {{ 1..1000000 | array.size }} and force large amounts of CPU work even when LoopLimit is set to a very small value. Details The relevant code path is: - ScriptBlockStatement.Evaluate() calls context.CheckAbort() once per statement in src/Scriban/Syntax/Statements/ScriptBlockStatement.cs lines 41–46. - LoopLimit enforcement is tied to script loop execution via TemplateContext.StepLoop(), not to internal helper iteration. - array.size in src/Scriban/Functions/ArrayFunctions.cs lines 596–609 calls list.Cast<object().Count() for non-collection enumerables. - 1..N creates a ScriptRange from ScriptBinaryExpression.RangeInclude() in src/Scriban/Syntax/Expressions/ScriptBinaryExpression.cs lines 745–748. - ScriptRange then yields every element one by one without going through StepLoop() in…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
TemplateContext caches type accessors by Type only, but those accessors are built using the current MemberFilter and MemberRenamer. When a TemplateContext is reused and the filter is tightened for a later render, Scriban still reuses the old accessor and continues exposing members that should now be hidden. Details The relevant code path is: - TemplateContext.GetMemberAccessor() caches accessors in memberAccessors by Type in src/Scriban/TemplateContext.cs lines 850–863. - For plain .NET objects, GetMemberAccessorImpl() creates a new TypedObjectAccessor(type, keyComparer, MemberFilter, MemberRenamer) in src/Scriban/TemplateContext.cs lines 909–939. - TypedObjectAccessor stores the current filter and precomputes the exposed member set in its constructor and PrepareMembers() in src/Scriban/Runtime/Accessors/TypedObjectAccessor.cs lines 33–40 and 119–179. - Member access later goes through ScriptMemberExpression.GetValue() in…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
TemplateContext.Reset() claims that a TemplateContext can be reused safely on the same thread, but it does not clear CachedTemplates. If an application pools TemplateContext objects and uses an ITemplateLoader that resolves content per request, tenant, or user, a previously authorized include can be served to later renders without calling TemplateLoader.Load() again. Details The relevant code path is: - TemplateContext.Reset() only clears output, globals, cultures, and source files in src/Scriban/TemplateContext.cs lines 877–902. - CachedTemplates is initialized once and kept on the context in src/Scriban/TemplateContext.cs line 197. - include resolves templates through IncludeFunction.Invoke() in src/Scriban/Functions/IncludeFunction.cs lines 29–43. - IncludeFunction.Invoke() calls TemplateContext.GetOrCreateTemplate() in src/Scriban/TemplateContext.cs lines 1249–1256. - If a template path is already present in CachedTemplates, Scriban returns the cached compiled template…
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
StackOverflowException via nested array initializers bypasses ExpressionDepthLimit fix (GHSA-wgh7-7m3c-fx25) Details The recent fix for GHSA-wgh7-7m3c-fx25 (uncontrolled recursion in parser) added ExpressionDepthLimit defaulting to 250. However, deeply nested array initializers ([[[...) recurse through ParseArrayInitializer → ParseExpression → ParseArrayInitializer, which is a different recursion path not covered by the expression depth counter. This causes a StackOverflowException on current main (commit b5ac4bf - "Add limits for default safety"). PoC Impact Same as GHSA-wgh7-7m3c-fx25: High severity. StackOverflowException cannot be caught with try/catch in .NET - the process terminates immediately. Any application calling Template.Parse with untrusted input is vulnerable, even with the new default ExpressionDepthLimit enabled.
Recommended action: Upgrade to 7.0.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
TemplateContext.LimitToString defaults to 0 (unlimited). While Scriban implements a default LoopLimit of 1000, an attacker can still cause massive memory allocation via exponential string growth. Doubling a string for just 30 iterations generates over 1GB of text, instantly exhausting heap memory and crashing the host process. Because no output size limit is enforced, repeated string concatenation results in exponential memory growth. Proof of Concept (PoC): The following payload executes in under 30 iterations but results in ~1GB string allocation, crashing the process. Impact: An attacker can supply a small template that triggers exponential string growth, forcing the application to allocate excessive memory. This leads to severe memory pressure, garbage collection thrashing, and eventual process termination (DoS). Suggested Fix: Enforce a sensible default limit for string output. Set default LimitToString to 1MB (1,048,576 characters).
Recommended action: Upgrade to 6.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
When Scriban renders an object that contains a circular reference, it traverses the object's members infinitely. Because the ObjectRecursionLimit property defaults to unlimited, this behavior exhausts the thread's stack space, triggering an uncatchable StackOverflowException that immediately terminates the hosting process. When rendering objects (e.g., {{ obj }}), the Scriban rendering engine recursively inspects and formats the object's properties. To prevent infinite loops caused by deeply nested or circular data structures, TemplateContext contains an ObjectRecursionLimit property. However, this property currently defaults to 0 (unlimited). If the data context pushed into the template contains a circular reference, the renderer will recurse indefinitely. This is especially dangerous for web applications that map user-controlled payloads (like JSON) directly to rendering contexts, or for applications that pass ORM objects (like Entity Framework models, which frequently contain…
Recommended action: Upgrade to 6.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Scriban is vulnerable to an uncontrolled process crash resulting in a Denial of Service. Because the recursive-descent parser does not enforce a default limit on expression depth, an attacker who controls template input can craft a heavily nested template that triggers a StackOverflowException. In .NET, a StackOverflowException cannot be caught by standard try-catch blocks, resulting in the immediate and ungraceful termination of the entire hosting process. Scriban utilizes a recursive-descent parser to process template expressions. While the library exposes an ExpressionDepthLimit property in its ParserOptions, this property defaults to null (disabled). If an application accepts user-supplied templates (or dynamically constructs templates from untrusted input), an attacker can supply thousands of nested parentheses or blocks. As the parser recursively evaluates each nested layer, it consumes thread stack space until it exceeds the limits of the host OS, triggering a fatal crash.…
Recommended action: Upgrade to 6.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.