Cloudanix VulnDB

CVE-2026-44646

Medium · 5.3

CVSS

5.3

EPSS

0.4%

Published

Jun 17, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

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

  1. Identify an application endpoint, CMS feature, email builder, theme editor, or template preview function that renders LiquidJS templates from untrusted or semi-trusted input.
  2. Confirm or infer that the application uses LiquidJS 10.25.7 or earlier and relies on per-render ownPropertyOnly:true controls.
  3. Submit a template containing a {% render %} tag that causes execution to enter a child render context.
  4. Place property-access expressions inside the rendered partial that attempt to resolve inherited or prototype-chain properties.
  5. Retrieve the rendered response or related output and inspect it for values that should have been blocked by own-property-only enforcement.
  6. 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