Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-61556

CVE-2026-61556: LiquidJS Template Engine DoS Vulnerability

CVE-2026-61556 is a denial of service flaw in LiquidJS template engine caused by an infinite loop in the strip_html filter. Attackers can block rendering with minimal input. This article covers technical details, affected versions, impact, and mitigation strategies.

Updated:

CVE-2026-61556 Overview

CVE-2026-61556 is an infinite loop vulnerability in LiquidJS, a Shopify and GitHub Pages compatible template engine written in pure JavaScript. The flaw resides in the strip_html filter implemented in src/filters/html.ts. Affected versions range from 10.26.0 up to but not including 10.27.1. An attacker can trigger an infinite loop by supplying an input string containing <, at least one preceding character, and no later >. The condition blocks template rendering entirely and causes denial of service. Input as short as a< is sufficient to trigger the loop. The issue is categorized under [CWE-835] (Loop with Unreachable Exit Condition).

Critical Impact

Unauthenticated remote attackers can trigger a denial of service in any application that passes user-controlled input through the strip_html filter, halting template rendering with a minimal payload.

Affected Products

  • LiquidJS versions 10.26.0 through 10.27.0
  • Applications using the strip_html filter with untrusted input
  • Downstream projects embedding LiquidJS for template rendering (Shopify-compatible and GitHub Pages-compatible pipelines)

Discovery Timeline

  • 2026-08-19 - CVE-2026-61556 published to NVD
  • 2026-08-19 - Last updated in NVD database
  • Version 10.27.1 - Patch released by the LiquidJS maintainers via GitHub Release v10.27.1

Technical Details for CVE-2026-61556

Vulnerability Analysis

The defect lives inside the strip_html filter loop that scans the input for HTML tag openers and closers. During each iteration, the code searches for the next opener and advances a tracking variable lt. When the closer search returns -1, the primary loop index i remains unchanged. The stall guard uses strict equality (i === lt) to detect a lack of progress and return early. Because i remains less than lt after the closer search fails, the equality check never fires. The loop reprocesses the same state indefinitely, consuming CPU and blocking the render thread. The minimum reproducer a< demonstrates that no complex payload is required.

Root Cause

The root cause is an incorrect stall-guard comparison operator. The pre-patch code used if (i === lt) return out + str.slice(lt), which only exits when the two indices match exactly. When lt advances past i without i progressing, the equality never holds and the loop continues. This is a classic loop termination condition error mapped to [CWE-835].

Attack Vector

Exploitation is network-reachable and requires no authentication or user interaction. Any endpoint that renders a Liquid template using the strip_html filter against attacker-controlled data is vulnerable. Typical attack surfaces include content management systems, storefronts, static site generators, and email rendering pipelines. A single malformed string blocks the rendering worker until the process is terminated.

typescript
      if (e >= 0) { i = e + closer.length; break }
      blocks.delete(opener)
    }
-    if (i === lt) return out + str.slice(lt)
+    if (i <= lt) return out + str.slice(lt)
  }
  return out
}

Source: GitHub Commit 5c3522f. The patch replaces the equality comparison with a less-than-or-equal comparison so the loop exits whenever i fails to advance past lt.

Detection Methods for CVE-2026-61556

Indicators of Compromise

  • Rendering worker processes pegged at 100% CPU for extended periods with no completion
  • HTTP request timeouts on endpoints that pass user input through Liquid templates
  • Node.js event loop lag spikes correlated with template rendering handlers
  • Application logs showing hung requests referencing the strip_html filter

Detection Strategies

  • Inventory dependencies with npm ls liquidjs and flag any version in the range 10.26.0 through 10.27.0
  • Add request-level timeouts around template rendering and log any timeouts referencing strip_html
  • Instrument the strip_html filter with input length and duration metrics to catch anomalous execution times
  • Fuzz test endpoints with short payloads containing an unmatched < character to confirm exposure

Monitoring Recommendations

  • Alert when Node.js event loop lag exceeds a defined threshold on services that render Liquid templates
  • Monitor per-request CPU time for template rendering paths and alert on sustained outliers
  • Track process restarts and worker crashes triggered by watchdog timeouts

How to Mitigate CVE-2026-61556

Immediate Actions Required

  • Upgrade LiquidJS to version 10.27.1 or later across all applications and build pipelines
  • Audit template code for strip_html usage on paths that receive untrusted input
  • Enforce request-level rendering timeouts to bound the impact of any remaining slow paths
  • Rebuild and redeploy static sites that were generated with a vulnerable LiquidJS version

Patch Information

The fix is available in LiquidJS 10.27.1. The maintainers merged Pull Request #917 and published Release v10.27.1. See GHSA-m7fp-h3p4-hr49 for the advisory. The change in src/filters/html.ts replaces the i === lt stall guard with i <= lt so the loop always terminates when the primary index fails to advance.

Workarounds

  • Remove or disable the strip_html filter in templates that process untrusted input until the patch is deployed
  • Pre-sanitize input strings by rejecting or escaping unmatched < characters before passing them to the filter
  • Wrap template rendering calls in a worker thread with a hard timeout to isolate infinite-loop conditions
bash
# Upgrade LiquidJS to the patched release
npm install liquidjs@^10.27.1

# Verify the resolved version
npm ls liquidjs

# Confirm no vulnerable version remains in the lockfile
grep -E '"liquidjs": "10\.(26|27\.0)' package-lock.json

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.