HIGH 7.5

CVE-2026-45357: LiquidJS Template Engine DoS via Unvalidated Width Specifiers

LiquidJS, a JavaScript template engine compatible with Shopify and GitHub Pages, has a denial-of-service vulnerability in versions 10.25.7 and earlier. The date filter's strftime implementation fails to validate width specifiers (e.g., %5000000d), allowing attackers to craft small templates that generate enormous amounts of output and consume excessive memory and CPU. The vulnerability bypasses built-in resource limits that documentation claims should prevent this type of attack. A single malicious template can trigger out-of-memory crashes or make applications unresponsive.

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-400
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 date filter's strftime implementation parses width specifiers like %9999999d and forwards the captured width unchecked into pad()/padStart(), leading to memory and render limit bypass. In src/util/underscore.ts, the pad loop performs unbounded string concatenation without consulting the Context's memoryLimit or renderLimit, so a single small template ({{ x | date: '%5000000d' }}) produces megabytes of output and unbounded CPU. The memoryLimit and renderLimit options the docs (src/liquid-options.ts:87-92) advertise as DoS controls — and which the docstring explicitly mentions for strftime — are entirely bypassed. Exploitation can cause large memory allocations, high CPU usage, or OOM crashes per render. 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-45357 stems from unsafe parsing of width specifiers in LiquidJS's strftime-based date filter implementation (src/util/underscore.ts). When a template includes a date filter with a large width value like {{ x | date: '%5000000d' }}, the parser extracts the width number and passes it directly to pad() and padStart() functions without bounds checking. These functions perform unbounded string concatenation without consulting the Context's memoryLimit or renderLimit settings, which are intended to be DoS safeguards. This allows a single small template to produce megabytes of output and cause excessive CPU consumption, potentially leading to out-of-memory conditions or application crashes during rendering.

Business impact

Organizations using LiquidJS for template rendering—particularly those processing user-supplied templates or handling multi-tenant scenarios—face denial-of-service risk. Attackers can submit crafted templates that consume server resources disproportionate to input size, degrading application availability or triggering unexpected crashes. This is especially critical in SaaS platforms, static site generators, and content management systems relying on LiquidJS to render user templates safely. Resource exhaustion can impact service availability and incur unexpected compute costs.

Affected systems

LiquidJS versions 10.25.7 and below are vulnerable. The fix is available in version 10.26.0. Any application or service using LiquidJS for template rendering with untrusted input should be assessed, including Shopify theme tools, GitHub Pages-adjacent workflows, or custom applications embedding LiquidJS as a sandboxed template engine.

Exploitability

Exploitability is straightforward and requires no special privileges or user interaction. An attacker needs only to craft a template string with a large width specifier and trigger rendering. The CVSS vector (AV:N/AC:L/PR:N/UI:N) reflects that the attack is network-accessible, requires low complexity, no privileges, and no user interaction. The vulnerability is practical to exploit in any scenario where user input is rendered as a template, making it a credible DoS threat in production systems.

Remediation

Upgrade LiquidJS to version 10.26.0 or later, which validates width specifiers before passing them to string padding functions. Verify the upgrade in your package.json or dependency manifest. If upgrading is not immediately feasible, implement strict input validation on template strings (e.g., reject templates with unusually large numeric specifiers) or restrict access to template rendering endpoints. Additionally, configure and enforce memory and CPU limits at the application or container level as a defense-in-depth measure.

Patch guidance

Update LiquidJS dependency to version 10.26.0 or newer using your package manager (npm, yarn, or pnpm). Run `npm update liquidjs` or update the version constraint in package.json and reinstall dependencies. Test rendering of existing templates to ensure compatibility. The fix is contained in the strftime width validation logic and should not require code changes in dependent applications. Verify the patch against the official LiquidJS GitHub releases or npm package registry.

Detection guidance

Monitor application logs for template rendering errors, memory spikes, or CPU exhaustion correlated with specific template submissions. Look for templates containing date filter patterns with unusually large numeric width specifiers (e.g., %[0-9]{6,}). In environments with access to source templates, scan for regex patterns matching date filters with suspicious width values. Application performance monitoring (APM) tools can highlight sudden resource consumption increases tied to template processing. Code review of user-submitted templates or template generation logic can identify malicious patterns proactively.

Why prioritize this

This vulnerability merits prompt patching due to its HIGH CVSS score (7.5), network accessibility, lack of authentication or user interaction requirements, and practical exploitability in any system rendering untrusted templates. The ability to bypass documented DoS protections makes it particularly concerning for multi-tenant or SaaS platforms. Organizations should prioritize patching systems that process user-supplied templates within 30 days.

Risk score, explained

The CVSS 7.5 HIGH score reflects a high-impact availability attack with no complexity barrier. The vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H indicates network accessibility, low attack complexity, no privilege or user interaction required, and a sole impact of availability (denial of service). While confidentiality and integrity are unaffected, the ability to reliably crash or degrade service availability without barriers justifies the HIGH rating. The vulnerability's trivial triggering mechanism—a malicious template string—and universal applicability to any LiquidJS deployment reinforce the priority.

Frequently asked questions

Does this vulnerability require authentication or special privileges to exploit?

No. The CVSS vector PR:N/UI:N indicates that no privileges or user interaction are required. Any attacker capable of submitting a template string to a system using LiquidJS can trigger the vulnerability. This includes unauthenticated users if templates are accepted from the internet.

Are versions above 10.26.0 definitely safe?

Yes. Version 10.26.0 implements bounds checking on width specifiers before they are passed to string padding functions, preventing the unbounded memory and CPU consumption. Verify you are running 10.26.0 or later with `npm list liquidjs` or equivalent in your package manager.

What if I cannot upgrade immediately?

Implement temporary mitigations: (1) Restrict access to template rendering endpoints via authentication or network controls, (2) validate and reject templates containing date filters with large width specifiers, (3) enforce strict memory and CPU limits at the OS or container level, and (4) monitor rendering performance for anomalies. Plan an upgrade to 10.26.0 as soon as feasible.

Why do memoryLimit and renderLimit options not prevent this attack?

The strftime width specifier parsing bypasses these checks entirely. The pad() function performs unbounded string concatenation without consulting the Context's limits, so even if memoryLimit is set in configuration, the strftime implementation ignores it. The fix corrects this by validating width values before any string operations occur.

This analysis is based on CVE-2026-45357 data and the vulnerability description provided. Patch version numbers, affected versions, and fix details are as stated in the source data; verify against the official LiquidJS GitHub repository and npm package registry for current release information. This explainer does not constitute legal advice or a guarantee of security. Organizations should conduct their own risk assessment and testing before deploying patches in production environments. No exploit code or weaponized proof-of-concept is included intentionally to prevent misuse. Source: NVD (public-domain), retrieved 2026-07-27. Analysis generated by SEC.co (claude-haiku-4-5).