GHSA-7jvp-hj45-2f2m: Scriban: Template Writes to Arbitrary CLR Properties via `TypedObjectAccessor` (Mass Assignment + `private` / `init` / `internal` Setter Bypass)
<!-- obsidian --><h2 data-heading="Description">Description</h2>
<p>When a host pushes a CLR object into a Scriban <code>TemplateContext</code> via the standard, documented pattern —</p>
<pre><code class="language-csharp">var so = new ScriptObject();
so["user"] = currentUser; // direct CLR reference
context.PushGlobal(so);
</code></pre>
<p>— <code>TypedObjectAccessor</code> exposes every public-getter property for <strong>both reading and writing</strong>, and writes land on the live host object and <strong>persist after <code>Render()</code> returns</strong>. The write path performs no <code>CanWrite</code> and no setter-visibility check, producing two related but distinct weaknesses:</p>
<p><strong>(A) Mass assignment of public setters — CWE-915 (originally F-002).</strong> Any <code>{ get; set; }</code> property is writable from template code (<code>{{ user.is_admin = true }}</code>, <code>{{ order.total_price = 0 }}</code>). This is "surprising but technically consistent with the setter being public" — and crucially, Scriban offers <strong>no way to expose such a property read-only</strong>, because <code>MemberFilter</code> is read/write-symmetric.</p>
<p><strong>(B) Access-modifier bypass — CWE-284 (originally F-007).</strong> Properties the developer <strong>deliberately</strong> restricted are also writable, because reflection ignores C# accessibility:</p>
Declaration | Developer intent | Actual behavior
-- | -- | --
{ get; set; } | writable | writable (mass assignment — A)
{ get; private set; } | only the owning class writes | template writes freely
{ get; internal set; } | only the declaring assembly writes | template writes freely
{ get; init; } | immutable after construction (C# 9 language guarantee) | template writes freely post-construction
<p>The <code>init</code>-only post-construction write — the highest false-positive risk — was explicitly confirmed against the shipped 7.2.1 package.</p>
<h2 data-heading="Affected Versions">Affected Versions</
Details
Original advisory: https://github.com/advisories/GHSA-7jvp-hj45-2f2m
More from GitHub Security Advisories
- criticalGHSA-g936-7jqj-mwv8: TSDProxy: Internal proxy auth token forwarded to backend services enables management API …2026-07-10
- highGHSA-fpg8-7664-jc5q: melange: Incomplete package integrity verification allows data section substitution2026-07-10
- mediumGHSA-48rx-c7pg-q66r: Excon does not redact additional sensitive/risky headers when following redirects2026-07-10
- highGHSA-h4g2-xfmw-q2c9: Clauster: Non-loopback deployments can serve the dashboard unauthenticated when auth.enab…2026-07-10
- mediumGHSA-rqq5-2gf9-4w4q: Secure Headers: CSP directive injection via sandbox, plugin_types, and report_to when giv…2026-07-10