CVE-2026-34166
Low · 3.7CVSS
3.7
EPSS
0.6%
Published
Apr 8, 2026
CISA due date
—
Cloudanix analysis
A flaw in a template-rendering library can let someone submit specially crafted content that uses far more memory than expected and may make an affected service crash or become unavailable.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
LiquidJS versions prior to 10.25.3 can undercount memory consumption when the `memoryLimit` option is enabled and a template uses the `replace` filter. The limiter accounts only for the input string, search pattern, and replacement string lengths, but the actual operation `str.split(pattern).join(replacement)` can produce output that is far larger when the search pattern appears many times. An attacker who can control Liquid template content or template-rendered input can trigger large memory amplification, bypass the intended denial-of-service protection, and potentially cause excessive garbage collection, process instability, or out-of-memory termination. The impact is availability-focused; confidentiality and integrity are not directly affected.
Why it matters to the business
Applications that render attacker-controlled or user-supplied LiquidJS templates may become slow, unstable, or unavailable if crafted templates consume far more memory than expected. This can interrupt web pages, build systems, content rendering workflows, email generation, documentation sites, or other services that rely on LiquidJS. The CVSS and EPSS values are low and there is no known KEV listing or mature public exploitation reported, but internet-facing services that allow untrusted template authoring should still prioritize remediation because denial-of-service flaws can be triggered remotely and cheaply once a working payload is known.
How an attack unfolds
An attacker first identifies an application path where LiquidJS templates or template fragments are rendered from untrusted input, such as a preview feature, CMS customization interface, email/template editor, site generator workflow, or API that accepts Liquid syntax. The attacker crafts a template that applies the `replace` filter to a string containing many repeated instances of a chosen pattern, using a replacement value that significantly expands the output. Because vulnerable LiquidJS versions charge the memory limiter based on only the original string, pattern, and replacement lengths rather than the expanded result, the render operation can pass the configured `memoryLimit` check while allocating substantially more memory during `split().join()`. Repeated requests or sufficiently large payloads can exhaust Node.js heap memory, force heavy garbage collection, terminate the process with an out-of-memory error, or degrade service responsiveness. Successful exploitation requires control over template content or equivalent rendering input and depends on how the application exposes LiquidJS rendering.
How to fix it
Upgrade LiquidJS to version 10.25.3 or later wherever it is used, including direct and transitive dependencies in applications, build pipelines, static site generation workflows, and services that render Liquid templates. Regenerate and redeploy dependency lockfiles after upgrading. If immediate upgrade is not possible, reduce exposure by disabling or restricting untrusted template rendering, blocking or sanitizing use of the `replace` filter in untrusted templates, enforcing strict request body/template size limits, adding render timeouts, running template rendering in isolated worker processes with operating-system or container memory limits, and applying rate limits to template preview or rendering endpoints. Do not rely solely on LiquidJS `memoryLimit` in affected versions as a protection against this issue.
How to confirm the fix worked
Confirm that dependency inventories, package lockfiles, and deployed artifacts show LiquidJS version 10.25.3 or later. For npm-based projects, check `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, SBOMs, and runtime images for `liquidjs` versions below 10.25.3. Exercise regression tests for legitimate templates that use `replace`, and perform controlled negative testing in a non-production environment with repeated-pattern replacement payloads to verify the renderer rejects, times out, or safely handles expansion without excessive memory growth. Validate that compensating controls are active where applicable: request size limits, render timeouts, worker/container memory ceilings, rate limits, and filter allowlists or denylists.
Typical attack path
- Locate an application feature or API endpoint that renders LiquidJS templates or user-controlled Liquid expressions.
- Confirm that the service accepts Liquid filters and that the `replace` filter is usable in the rendering context.
- Submit a crafted template that creates a string with many repeated occurrences of a selected pattern.
- Apply the `replace` filter with a replacement that expands the string much more than the vulnerable memory accounting anticipates.
- Trigger one or more render operations to cause excessive memory allocation, CPU pressure from garbage collection, or Node.js process failure.
- Repeat requests as needed to sustain application degradation or denial of service.
How to detect it
Look for evidence of availability attacks against LiquidJS rendering paths. Relevant log sources include application access logs, API gateway/WAF logs, Node.js application logs, container orchestration events, process supervisor logs, crash dumps, APM traces, and operating-system memory/OOM logs. Focus on endpoints that accept templates, previews, CMS content, page generation input, email templates, or API-submitted Liquid syntax. Indicators include repeated requests containing Liquid `replace` filters, unusually large repeated-character strings, spikes in render duration, sudden Node.js heap growth, garbage-collection pressure, HTTP 500/502/503 responses after template submissions, container restarts, and out-of-memory kill events. If threat hunting historical activity, correlate suspicious template submissions with process restarts or memory exhaustion within the same time window. There are no widely reported CVE-specific attacker tools or fixed network signatures, so detection should combine content-pattern searches with resource-exhaustion telemetry.
- | replace:
- |replace:
- replace filter
- JavaScript heap out of memory
- FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
- FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
- Allocation failed - JavaScript heap out of memory
- str.split(pattern).join(replacement)
- OOMKilled
- Out of memory: Killed process
- Container killed due to memory usage
- liquidjs
- node --max-old-space-size
What your security team should do
- Inventory all applications, services, CI/CD jobs, and content-generation workflows that include the `liquidjs` package.
- Prioritize internet-facing or multi-tenant features where untrusted users can create, edit, preview, or submit Liquid templates.
- Upgrade LiquidJS to 10.25.3 or later and redeploy affected services and build images.
- Add or verify defense-in-depth controls for template rendering, including input size limits, render timeouts, rate limiting, and process/container memory limits.
- If untrusted templates are supported, consider restricting high-risk filters such as `replace` or implementing a strict filter allowlist.
- Monitor application and platform telemetry for Node.js heap exhaustion, process restarts, abnormal render latency, and repeated template-rendering errors.
- Search historical logs for suspicious use of Liquid `replace` patterns, especially around endpoints that render previews or accept template content.
- Track dependency updates for downstream packages that bundle or depend on LiquidJS, even if LiquidJS is not declared as a top-level dependency.
The record
LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to 10.25.3, the replace filter in LiquidJS incorrectly accounts for memory usage when the memoryLimit option is enabled. It charges str.length + pattern.length + replacement.length bytes to the memory limiter, but the actual output from str.split(pattern).join(replacement) can be quadratically larger when the pattern occurs many times in the input string. This allows an attacker who controls template content to bypass the memoryLimit DoS protection with approximately 2,500x amplification, potentially causing out-of-memory conditions. This vulnerability is fixed in 10.25.3.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | liquidjs | 0 | 10.25.3 |
Related vulnerabilities
- GHSA-mmg9-6m6j-jqqx LiquidJS Has Memory Limit Bypass via Quadratic Amplification in `replace` Filter 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-44646 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