CVE-2026-33287: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-33287 is an exponential memory amplification vulnerability in the LiquidJS replace_first filter that allows unauthenticated attackers to cause denial of service by bypassing the configured memoryLimit. The flaw affects all LiquidJS (npm) versions up to and including 10.24.0 running on Node.js. It was published on March 25, 2026, by maintainer harttle via GitHub Security Advisory GHSA-6q5m-63h6-5x4v, and assigned a CVSS v3.1 base score of 7.5 (High) (GitHub Advisory).

Technical details

The root cause (CWE-20: Improper Input Validation; CWE-400: Uncontrolled Resource Consumption) lies in src/builtin/filters/string.ts, where replace_first delegates to JavaScript's native String.prototype.replace(). This method interprets $& as a backreference that expands to the entire matched substring, but the filter only calls memoryLimit.use(str.length) for the input string — the amplified output is never charged against the memory budget. An attacker can chain five replace_first stages, each using 50 repetitions of $&, to achieve a 625,000:1 amplification ratio (1 byte input → 312.5 MB output) while consuming only ~6.38 MB of the memoryLimit counter. The sibling replace filter is safe because it uses str.split().join(), which treats $& as a literal string. A detailed PoC with Node.js code and bash scripts is publicly available in the security advisory (GitHub Advisory).

Impact

Exploitation has no confidentiality or integrity impact, but delivers a severe availability impact against any Node.js service that renders user-supplied Liquid templates (e.g., CMS platforms, newsletter editors, SaaS applications). A single malicious request allocates up to 625 MB of heap memory and blocks the Node.js event loop; with 20 concurrent attack requests, legitimate user latency degrades by up to 2,180× and the server becomes completely unresponsive for approximately 29 seconds per attack wave. The attack payload is only ~500 bytes per HTTP request, making it highly cost-efficient for sustained denial-of-service campaigns (GitHub Advisory).

Exploitability

A high-confidence proof-of-concept exploit — including concrete Liquid template payloads, curl commands, and a bash script demonstrating concurrent DoS — is publicly available in the GitHub Security Advisory (GitHub Advisory). No authentication or special privileges are required; the only precondition is that the target application accepts user-controlled Liquid templates. The EPSS score is approximately 0.044% (12th percentile), and there is no current evidence of in-the-wild exploitation or CISA KEV catalog inclusion. No threat actor attribution has been reported.

Exploitation steps

  1. Identify a target: Locate a web application that accepts user-supplied Liquid templates for rendering (e.g., a newsletter preview endpoint, CMS template editor, or SaaS platform) running LiquidJS ≤ 10.24.0.
  2. Craft the amplification payload: Construct a Liquid template that chains five replace_first calls, each using 50 repetitions of $& as the replacement string:
    {% assign s = "A" %}
    {% assign s = s | replace_first: s, "$&$&$&...(50 times)...$&" %}
    {% assign s = s | replace_first: s, "$&$&$&...(50 times)...$&" %}
    {% assign s = s | replace_first: s, "$&$&$&...(50 times)...$&" %}
    {% assign s = s | replace_first: s, "$&$&$&...(50 times)...$&" %}
    {% assign s = s | replace_first: s, "$&$&$&...(50 times)...$&" %}
    {{ s }}
    Each stage amplifies the string 50×; five stages yield 50^5 = 312,500,000 characters (~312.5 MB).
  3. Send the payload: Submit the template via HTTP POST to the rendering endpoint:
    curl -s -X POST http://<target>/render \
      -H "Content-Type: application/x-www-form-urlencoded" \
      --data-urlencode 'template=<payload>'
  4. Launch concurrent requests for DoS: Send 20 simultaneous copies of the payload using a bash loop to saturate the Node.js event loop and cause sustained service unavailability for all legitimate users.
  5. Observe impact: Legitimate requests sent during the attack window experience 10+ second delays (up to 2,180× baseline latency), and the server remains blocked for ~29 seconds per attack wave (GitHub Advisory).

Indicators of compromise

  • Network: High volume of HTTP POST requests to template rendering endpoints (e.g., /render, /newsletter/preview) with large template body parameters containing repeated $& substrings; unusually large HTTP responses (~312 MB) from the template rendering endpoint; concurrent requests from the same or multiple source IPs targeting the rendering endpoint.
  • Logs: Application/access logs showing many simultaneous POST requests to the template endpoint with response times exceeding 10 seconds; Node.js process logs indicating high memory usage or out-of-memory events; requests with Content-Type: application/x-www-form-urlencoded or application/json containing replace_first and $& patterns in the body.
  • Process/Runtime: Node.js process heap usage spiking to 500–625 MB during request processing; event loop lag metrics exceeding several seconds; CPU utilization remaining high for extended periods during template rendering (GitHub Advisory).

Mitigation and workarounds

Upgrade LiquidJS to version 10.25.1 or later, which fixes the vulnerability by changing replace_first to use a function-form replacement (() => arg2) that prevents $& backreference expansion, and also correctly accounts for all argument lengths in memoryLimit (Patch Commit). If immediate patching is not possible, implement request rate limiting and concurrency controls at the application or infrastructure level to limit simultaneous template rendering requests. Additionally, consider deploying a WAF rule to detect and block requests containing $& patterns in template parameters, and monitor Node.js event loop latency and heap usage for early detection of exploitation attempts (GitHub Advisory).

Community reactions

The vulnerability was reported by researcher koDove and published by the LiquidJS maintainer (harttle) on March 25, 2026. Brief mentions appeared on Mastodon and Bluesky CVE tracking accounts shortly after disclosure. No significant vendor statements beyond the advisory or notable media coverage have been identified.

Additional resources


Source: This report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-gvwc-5hr5-44p8HIGH7.5
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5jh3-w3fj-6758LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5v8x-rm7w-m4c7LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-7pqp-3q23-mwr8LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-3qg4-7mq2-gm93MEDIUMN/A
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management