CVE-2026-44646
Medium · 5.3CVSS
5.3
EPSS
0.4%
Published
Jun 17, 2026
CISA due date
—
Cloudanix analysis
Some applications using this template library may accidentally reveal hidden data when rendering user-controlled templates with nested partials.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Data Exposure
- Component
- Library
- Class
- Information Disclosure
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
LiquidJS versions 10.25.7 and earlier contain an information disclosure flaw in Context.spawn(), which is used when processing the Liquid {% render %} tag. When an application creates a Liquid instance with ownPropertyOnly:false for backward compatibility, but attempts to enforce safer behavior for a specific untrusted render by calling parseAndRender(..., { ownPropertyOnly: true }), that per-render restriction is not propagated into the child context created for {% render %}. The rendered partial may therefore resolve properties through the JavaScript prototype chain even though the caller intended to restrict access to an object’s own properties only. This can expose unintended prototype-chain properties or application data reachable through object prototypes. The issue is fixed in LiquidJS 10.26.0.
Why it matters to the business
Applications that allow users, partners, CMS editors, or other untrusted parties to control Liquid templates or partials may leak data the application expected to hide. The operational risk is highest for multi-tenant content rendering, email/template builders, documentation platforms, storefront customization, and server-side rendering workflows that rely on ownPropertyOnly:true as a security boundary. This is not currently listed in CISA KEV, has no known ransomware association, and has low EPSS, so broad exploitation is not indicated; however, exposure can be subtle because affected renders may appear to complete normally while leaking data.
How an attack unfolds
An attacker first needs a path to submit or influence a Liquid template that is rendered by an affected LiquidJS application. The target application must use a Liquid instance configured with ownPropertyOnly:false while attempting to lock down a specific untrusted render with parseAndRender(..., { ownPropertyOnly: true }). The attacker includes a {% render %} tag that invokes a partial under their control or a partial that can be influenced. Because Context.spawn() creates a child context for the render operation without carrying forward the per-render ownPropertyOnly:true override, property resolution inside the partial falls back to the instance-level ownPropertyOnly:false setting. The attacker then references prototype-chain properties from inside the rendered partial and observes the rendered output, error output, logs, or downstream response to recover data that should not have been accessible from the template context.
How to fix it
Upgrade LiquidJS to version 10.26.0 or later wherever it is used. If exact package management controls are available, ensure package-lock.json, yarn.lock, pnpm-lock.yaml, shrinkwrap files, container images, bundled frontend/server artifacts, and transitive dependency pins all resolve to a fixed LiquidJS version. As a defense-in-depth measure, avoid using ownPropertyOnly:false for rendering untrusted templates; use isolated rendering contexts that contain only explicitly intended data; do not expose rich application objects, class instances, request objects, process objects, secrets, or configuration objects to templates; and restrict user control over {% render %} partial names and partial content. If immediate upgrade is not possible, disable or tightly constrain untrusted use of {% render %}, prevent user-supplied partials, and enforce template review or allowlisting until the fixed version is deployed.
How to confirm the fix worked
Confirm the deployed dependency tree resolves LiquidJS to 10.26.0 or later using the relevant package manager, such as npm ls liquidjs, yarn why liquidjs, pnpm why liquidjs, or software composition analysis tooling. Validate built artifacts and containers, not only source repositories, because older versions may be bundled. Add a regression test that initializes LiquidJS with ownPropertyOnly:false, calls parseAndRender with { ownPropertyOnly: true }, renders a template using {% render %}, and verifies that inherited or prototype-chain properties are not accessible inside the partial. Review application template security tests to ensure {% render %} is covered separately from Liquid filters such as where, reject, group_by, find, find_index, and has.
Typical attack path
- Identify an application endpoint, CMS feature, email builder, theme editor, or template preview function that renders LiquidJS templates from untrusted or semi-trusted input.
- Confirm or infer that the application uses LiquidJS 10.25.7 or earlier and relies on per-render ownPropertyOnly:true controls.
- Submit a template containing a {% render %} tag that causes execution to enter a child render context.
- Place property-access expressions inside the rendered partial that attempt to resolve inherited or prototype-chain properties.
- Retrieve the rendered response or related output and inspect it for values that should have been blocked by own-property-only enforcement.
- Repeat with different reachable objects or partials to enumerate additional exposed properties.
How to detect it
To assess prior exploitation, review application access logs, template-rendering audit logs, CMS/theme/editor activity logs, preview endpoint logs, and server-side error logs for unusual Liquid templates that combine {% render %} with attempts to access prototype-related properties. Focus on endpoints where users can submit, preview, save, or publish Liquid templates or partials. Look for repeated rendering attempts, template syntax errors, probes for JavaScript object internals, and output containing values that should not normally appear in rendered templates. If template source is stored, examine recently created or modified templates and partials for {% render %} usage paired with property names such as __proto__, prototype, constructor, toString, valueOf, hasOwnProperty, or inherited application-specific properties. Also review dependency and deployment history to determine whether vulnerable versions were active during the period when suspicious templates were submitted. There are no public threat actors or known exploitation campaigns associated with this CVE in the provided intelligence.
- {% render
- ownPropertyOnly:false
- ownPropertyOnly: false
- ownPropertyOnly:true
- ownPropertyOnly: true
- parseAndRender(
- __proto__
- prototype
- constructor
- hasOwnProperty
- toString
- valueOf
- Context.spawn
- liquidjs@10.25.7
- "liquidjs": "10.25.7"
- "liquidjs":"10.25.7"
What your security team should do
- Inventory all applications and services using LiquidJS, including indirect and bundled dependencies.
- Prioritize upgrades to LiquidJS 10.26.0 or later for systems that render user-controlled or tenant-controlled templates.
- Search code for parseAndRender calls using ownPropertyOnly:true and Liquid instances or configuration using ownPropertyOnly:false, as this combination indicates the vulnerable security assumption.
- Identify places where {% render %} can be supplied, influenced, or selected by untrusted users and restrict that capability until upgraded.
- Review rendered output logs, template preview logs, and application error logs for suspicious property-probing activity involving render partials and prototype-related names.
- Add regression tests for ownPropertyOnly enforcement across nested render contexts.
- Reduce template context data to minimal plain objects and avoid exposing sensitive runtime objects to any template engine.
The record
LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. In versions 10.25.7 and below, Context.spawn() creates a child Context for the {% render %} tag but does not propagate the parent context's resolved ownPropertyOnly value, resulting in a silent bypass. The new context re-derives ownPropertyOnly from opts.ownPropertyOnly (the instance-level option), silently discarding any RenderOptions.ownPropertyOnly override that was supplied to parseAndRender(). As a result, a developer who runs a Liquid instance with the backwards-compatible ownPropertyOnly:false and then locks down an untrusted render with parseAndRender(..., { ownPropertyOnly: true }) still leaks prototype-chain properties from inside any {% render %} partial. This is a distinct exploit surface from the previously identified array-filter variants (where, reject, group_by, find, find_index, has) — the underlying root cause in Context.spawn() is shared, but {% render %} is a separately reachable sink that needs no filter usage. This issue has been fixed in version 10.26.0.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | liquidjs | 0 | No fix |
Related vulnerabilities
- GHSA-9x9p-qf8f-mvjg LiquidJS's `{% render %}` tag silently bypasses per-render `ownPropertyOnly:true` via… Same vulnerability
- CVE-2026-45617 LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. Also affects liquidjs
- CVE-2026-45357 LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. Also affects liquidjs
- CVE-2026-44645 LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. Also affects liquidjs
- CVE-2026-44644 LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. Also affects liquidjs
- GHSA-gf2q-c269-pqgc LiquidJS is Vulnerable to Remote Code Execution Also affects liquidjs
- GHSA-r7g9-xpmj-5fcq LiquidJS Vulnerable to ReDoS via Quadratic Backtracking in `strip_html` Filter Regex Also affects liquidjs
- GHSA-hh27-hf48-9f5q LiquidJS has a memory and render limit bypass via unbounded width padding in `date`… Also affects liquidjs