🛡️ GHSA-x6m9-38vm-2xhf — scriban

🟠 CVSS 8.0 — High ✅ No Known Exploit CWE-226 OSV
8.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Scriban has an authorization bypass due to stale include cache surviving TemplateContext.Reset()

Summary

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 and does not call TemplateLoader.Load() again.

This becomes a security issue when ITemplateLoader.Load() returns request-dependent content. A first render can prime the cache with an admin-only or tenant-specific template, and later renders on the same reused TemplateContext will receive that stale template even after Reset().

Proof of Concept

Setup

```bash

mkdir scriban-poc1

cd scriban-poc1

dotnet new console --framework net8.0

dotnet add package Scriban --version 6.6.0

```

Program.cs

```csharp

using Scriban;

using Scriban.Parsing;

using Scriban.Runtime;

var loader = new SwitchingLoader();

var context = new TemplateContext

{

TemplateLoader = loader,

};

var template = Template.Parse("{{ include 'profile' }}");

loader.Content = "admin-only";

Console.WriteLine("first=" + template.Render(context));

context.Reset();

loader.Content = "guest-view";

Console.WriteLine("second=" + template.Render(context));

sealed class SwitchingLoader : ITemplateLoader

{

public string Content { get; set; } = string.Empty;

public string GetPath(TemplateContext context, SourceSpan callerSpan, string templateName) => templateName;

public string Load(TemplateContext context, SourceSpan callerSpan, string templatePath) => Content;

public ValueTask<string> LoadAsync(TemplateContext context, SourceSpan callerSpan, string templatePath)

=> new(Content);

}

```

Run

```bash

dotnet run

```

Actual Output

```

first=admin-only

second=admin-only

```

Expected Output

```

first=admin-only

second=guest-view

```

The second render should reload the template after Reset(), but it instead reuses the cached compiled template from the previous render.

Impact

This is a cross-render data isolation issue. Any application that reuses TemplateContext objects and uses a request-dependent ITemplateLoader can leak previously authorized template content across requests, users, or tenants.

The issue impacts applications that:

  • Pool or reuse TemplateContext
  • Call Reset() between requests
  • Use include
  • Resolve include content based on request-specific state

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality high, integrity none, availability none.

Weakness class

GHSA-x6m9-38vm-2xhf is classified as CWE-226: Sensitive Information in Resource Not Removed Before Reuse. The product releases a resource such as memory or a file so that it can be made available for reuse, but it does not clear or "zeroize" the information contained in the resource before the product performs a critical state transition or makes the…

Affected software

GHSA-x6m9-38vm-2xhf is recorded against 2 packages.

  • scriban (fixed in 7.0.0)
  • scriban.signed (fixed in 7.0.0)

Timeline and source

Published on 24 March 2026 and last revised on 6 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Web)
github.com (Package)

Details

Severity HIGH
CVSS Score 8.0
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
CWE CWE-226
Public Exploit ✅ No
Source OSV
Published 2026-03-24
Updated 2026-08-12
Modified 2026-07-06
Fix URL N/A

Affected Packages

Software From version Fixed in
scriban 7.0.0
scriban.signed 7.0.0

Site Security Check

Is scriban part of your stack?

GHSA-x6m9-38vm-2xhf is rated CVSS 8.0 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesGitHub AdvisoryGitHub Advisory Undated