HIGH 7.5

CVE-2026-45617: LiquidJS strip_html ReDoS Denial of Service Vulnerability

LiquidJS, a popular template engine used by Shopify and GitHub Pages, contains a denial-of-service flaw in its strip_html filter that can freeze Node.js applications. Attackers can craft malicious input—such as 350 KB of repeated `<script` tags—that causes the filter's underlying regex to perform excessive backtracking, consuming CPU and blocking the event loop for seconds. This happens without any authentication required, making it trivial to exploit via a single HTTP request containing untrusted template data. The vulnerability affects all versions up to 10.25.7 and is resolved in 10.26.0.

Source data · NVD / CISA · public domain

CVSS
3.1 · 7.5 HIGH · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weaknesses (CWE)
CWE-1333
Affected products
0 configuration(s)
Published / Modified
2026-06-17 / 2026-06-22

NVD description (verbatim)

LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. In versions 10.25.7 and below, the built-in strip_html filter uses a regex containing four flawed lazy-quantified alternatives, leading to ReDoS via quadratic backtracking. When the input contains many <script, <style, or <!-- opener tokens without matching closers, the V8 regex engine performs O(N²) backtracking, blocking the Node.js event loop. A single ~350 KB request ('<script'.repeat(50000)) stalls the process for ~10 seconds; cost grows quadratically with input size. The default memoryLimit: Infinity does not bound regex CPU, and even when configured strip_html only charges str.length to the limit — the regex itself runs unbounded. A single unauthenticated request containing crafted untrusted input can cause severe event-loop blocking and CPU amplification that saturates Node.js workers while bypassing memoryLimit protections. This issue has been fixed in version 10.26.0.

4 reference(s) · View on NVD →

SEC.co analysis · AI-assisted, reviewed against source

Technical summary

CVE-2026-45617 is a regular expression denial of service (ReDoS) vulnerability in LiquidJS's strip_html filter. The filter uses a regex pattern with four lazy-quantified alternatives that exhibit catastrophic backtracking behavior when processing malformed input. Specifically, when the input contains multiple opening tokens (`<script`, `<style`, `<!--`) without corresponding closers, the V8 engine's regex matcher backtracks quadratically: a 350 KB payload induces ~10 seconds of CPU stalling, with blocking time scaling as O(N²) relative to input size. The vulnerability persists even when LiquidJS is configured with a memoryLimit, because the regex engine operates outside the memory-charge mechanism—only the string length is counted against the limit, not regex CPU cost. This allows a single unauthenticated request to saturate Node.js worker threads and degrade or halt service availability.

Business impact

Organizations deploying LiquidJS—particularly those rendering user-supplied or third-party templates in web services—face a straightforward denial-of-service risk. An attacker can send a single HTTP POST or GET request containing crafted template input to reliably stall the application for seconds, causing request timeouts and user-facing unavailability. Multi-worker setups (e.g., cluster or load-balanced deployments) can be saturated if multiple requests are sent concurrently. Recovery requires application restart. This is especially critical for platforms offering template customization or dynamic template rendering without strict input validation, and for systems where template processing is on the hot path of request handling.

Affected systems

LiquidJS versions 10.25.7 and earlier are vulnerable. The vulnerability affects any Node.js application that uses LiquidJS to render templates, particularly those that accept untrusted or user-supplied template strings and pass them through the strip_html filter. Common scenarios include: Shopify custom app backends, static site generators (e.g., Jekyll plugins using LiquidJS), content management systems with template customization, and any service that processes template data from external sources. The exact scope of third-party integrations depends on adoption of vulnerable LiquidJS versions in downstream packages.

Exploitability

Exploitability is very high. No authentication, special privileges, or user interaction is required. An attacker can craft the malicious input locally, verify the payload size and backtracking cost in a test environment, and then send a single HTTP request to a vulnerable application. Public proof-of-concept is trivial: `'<script'.repeat(50000)` embedded in template data causes observable stalling. The attack surface is broad wherever untrusted input reaches the strip_html filter or template rendering pipeline. The only practical barriers are network-level input size limits (e.g., max POST body size) or explicit input validation before passing data to LiquidJS.

Remediation

Upgrade LiquidJS to version 10.26.0 or later, which contains a corrected regex pattern that avoids catastrophic backtracking. For applications that cannot upgrade immediately, implement mitigation: validate and sanitize template input before rendering (reject unexpectedly large payloads or strings with excessive consecutive opening tags), configure web server or application-level request size limits to reject payloads larger than typical template sizes, and consider disabling or guarding the strip_html filter if it is not essential to your use case. Monitor Node.js event loop lag and CPU usage to detect exploitation attempts.

Patch guidance

Verify your LiquidJS version using `npm list liquidjs` or by checking package-lock.json. If 10.25.7 or earlier is in use, upgrade by running `npm install [email protected]` (or the latest stable version). Update your package.json and verify compatibility with your application's other dependencies before deploying to production. The fix is contained in LiquidJS's regex pattern for the strip_html filter; no configuration changes or API migrations are needed. Test template rendering with your existing test suite to confirm no behavioral regressions. If you maintain a dependency on an older LiquidJS version through a transitive dependency, request that upstream package maintainers update their LiquidJS requirement.

Detection guidance

Monitor for exploitation by observing Node.js event loop latency and CPU usage spikes correlated with incoming requests. Enable application performance monitoring (APM) to log requests that trigger extended regex execution times. At the network level, log and alert on requests with unusually large payloads or repetitive malformed HTML-like sequences (e.g., many consecutive `<script` or `<!--` tokens). In application logs, look for entries showing template rendering delays or timeouts. If you have access to LiquidJS internals, instrument the strip_html filter to measure regex execution time and flag slow operations. Query web server logs for POST/GET requests with payloads in the hundreds of kilobytes range directed at template rendering endpoints.

Why prioritize this

This vulnerability merits immediate patching because: (1) CVSS 7.5 (HIGH) reflects significant availability impact; (2) exploitability is trivial—no special tools, authentication, or user interaction needed; (3) the attack surface is broad for any service accepting user templates; (4) impact is severe and user-facing (service stalling); (5) the patch is simple and low-risk (regex fix with no API changes); (6) the vulnerability is public and likely to be targeted once widely known. Organizations should prioritize patching production services before considering lower-criticality updates.

Risk score, explained

CVSS 3.1 score of 7.5 reflects a HIGH severity: Network Attack Vector (AV:N), Low Attack Complexity (AC:L), No authentication required (PR:N), No user interaction (UI:N), scope unchanged (S:U), no confidentiality or integrity impact, but high availability impact (A:H). The score appropriately captures that an unauthenticated attacker can remotely and trivially degrade or halt service availability, but does not account for data breach or system compromise. In practical terms, the severity is driven by the ease of exploitation and direct impact on application uptime rather than stealth or lateral movement potential.

Frequently asked questions

Does this vulnerability require the attacker to know specific details about my application?

No. The attack is completely generic: any application running a vulnerable LiquidJS version and rendering untrusted template input is at risk. An attacker does not need to know which version you are running, how you call strip_html, or any application-specific details. A single, simple payload works against all vulnerable instances.

Can I mitigate this without upgrading if my application never calls strip_html?

Partially. If your application never explicitly uses the strip_html filter, you reduce (but do not eliminate) risk. However, strip_html may be invoked implicitly by other filters or template directives, or by user-supplied templates that reference it directly. The safest mitigation is to validate and size-limit untrusted input before rendering, and to upgrade to 10.26.0 when feasible.

If I set memoryLimit on the LiquidJS engine, am I protected from this attack?

No. The memoryLimit configuration only tracks heap allocation and charges string lengths against the limit; it does not constrain the CPU cost of regex operations. The backtracking happens in the V8 regex engine outside the memory-charge mechanism, so the attack succeeds even with strict memory limits enabled.

How long does it take to exploit this, and can it be detected?

Exploitation requires only seconds: craft the malicious input, send one HTTP request. It can be detected via event loop latency monitoring, CPU spikes, request timeouts, and APM tools that log slow template rendering. Network-level detection is possible by identifying unusually large payloads with repetitive malformed HTML patterns. However, detection alone does not prevent the impact—upgrading or mitigating input size is necessary.

This analysis is provided for informational purposes and reflects the state of the vulnerability as of the publication date. Security assessments, patch release timelines, and vendor response may evolve. Organizations should verify all claims against official LiquidJS releases, review their own dependency trees, and conduct testing before deployment. This document does not constitute legal or professional security advice; consult your security team and vendor documentation for your specific environment. No exploit code or weaponization details are provided herein. Source: NVD (public-domain), retrieved 2026-07-27. Analysis generated by SEC.co (claude-haiku-4-5).