CVE-2026-44644
Medium · 6.1CVSS
6.1
EPSS
0.4%
Published
Jun 17, 2026
CISA due date
—
Cloudanix analysis
Some websites using this template library may fail to remove malicious web code from user-submitted text, allowing attackers to make that code run in other people’s browsers.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Low
- Impact
- Data Exposure
- Component
- Library
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
LiquidJS versions 10.25.7 and earlier contain a cross-site scripting weakness in the strip_html filter. The filter is intended to remove HTML tags before rendering user-controlled content, but its regular expression does not treat newline or carriage-return characters as part of the catch-all tag match. As a result, HTML tags containing line breaks, such as an image tag with an event handler split across lines, can pass through the filter intact. Because browsers treat line breaks inside HTML tags as whitespace, the resulting tag is still valid and can execute client-side JavaScript when rendered. The issue affects applications that rely on {{ value | strip_html }} as an XSS defense and do not separately HTML-escape the output.
Why it matters to the business
If an application uses vulnerable LiquidJS templates to display untrusted content, attackers may be able to run JavaScript in another user’s browser. This can lead to account takeover, session theft where cookies or tokens are accessible to scripts, fraudulent user actions, defacement, phishing inside trusted pages, or exposure of sensitive data shown in the affected application. The CVSS score is moderate and EPSS is currently low, with no known KEV listing or public exploit maturity indicated, but the vulnerability is easy to trigger where the unsafe template pattern exists.
How an attack unfolds
An attacker first identifies an application feature that stores or reflects user-controlled text rendered through the LiquidJS strip_html filter. They then submit HTML containing a newline or carriage return inside a tag, often combined with an event handler such as onerror, onload, autofocus, or similar browser-executed attributes. The vulnerable filter fails to remove the tag because its regex does not match across line terminators. When another user views the page, the browser parses the line breaks as normal whitespace inside the tag and executes the embedded script. The attacker’s script then runs in the security context of the affected site, allowing theft of accessible data, unauthorized actions as the victim, or redirection to malicious content.
How to fix it
Upgrade LiquidJS to version 10.26.0 or later. Review application templates for uses of strip_html on untrusted input, especially patterns like {{ value | strip_html }} where the output is not also HTML-escaped. Do not treat strip_html as a complete XSS sanitizer for untrusted content. Prefer context-aware output encoding and a proven HTML sanitizer where limited HTML is intentionally allowed. If immediate upgrade is not possible, enable output escaping where supported, explicitly HTML-escape filtered output, reject or neutralize angle brackets in untrusted fields before rendering, and add defense-in-depth controls such as a restrictive Content Security Policy that reduces the impact of inline script execution.
How to confirm the fix worked
Confirm dependency resolution shows LiquidJS 10.26.0 or later in every deployed package, lockfile, container image, and build artifact. Search templates for strip_html usage on user-controlled values and verify those outputs are also contextually escaped or sanitized with a robust sanitizer. Test representative affected views with benign newline-containing HTML tags, such as an image tag split across lines with a harmless event handler, and confirm the rendered page does not contain executable HTML. Validate browser output by inspecting the DOM, not only the server response, because browsers normalize line breaks inside tags. Add regression tests covering tags with \n and \r inside them.
Typical attack path
- Find a page or workflow that accepts user-controlled text and later renders it through LiquidJS templates.
- Determine whether the application relies on the strip_html filter as the primary HTML sanitization control.
- Submit a payload containing an HTML tag with a newline or carriage return inside the tag body.
- Include a browser-executed event handler or other script execution vector in the malformed-but-valid tag.
- Wait for a victim user to view the rendered content.
- The vulnerable filter leaves the newline-containing tag intact, and the victim’s browser executes the attacker-controlled JavaScript.
- Use the script execution context to steal accessible data, perform actions as the victim, alter page content, or redirect the victim.
How to detect it
To determine whether exploitation has already occurred, search application access logs, request bodies, WAF logs, reverse proxy logs, API gateway logs, and stored content repositories for submitted HTML tags containing newline or carriage-return characters inside the tag, especially combined with JavaScript event-handler attributes. Review fields that later render into Liquid templates, such as comments, profiles, markdown/CMS content, product descriptions, support tickets, messages, and other user-editable text. Look for encoded variants as well as raw payloads, including percent-encoded line breaks (%0a, %0d), HTML entities, and JSON-escaped line breaks. In browser telemetry or CSP violation reports, look for blocked inline script execution or unexpected image/script loading from pages that display user-generated content. If suspicious payloads are found, correlate the first submission time with page views by other users, session anomalies, account setting changes, unauthorized transactions, administrative actions, and outbound requests initiated from affected pages.
- <img\nsrc=x\nonerror=
- <img\rsrc=x\ronerror=
- %3Cimg%0Asrc%3Dx%0Aonerror%3D
- %3Cimg%0Dsrc%3Dx%0Donerror%3D
- <svg\nonload=
- <svg\ronload=
- %3Csvg%0Aonload%3D
- %3Csvg%0Donload%3D
- <body\nonload=
- <iframe\nsrc=
- <details\nopen\nontoggle=
- <input\nautofocus\nonfocus=
- onerror=alert(
- onload=alert(
- javascript:alert(
- \nonscroll=
- \nonmouseover=
- \nonmouseenter=
What your security team should do
- Prioritize upgrading LiquidJS to 10.26.0 or later in all applications that render user-controlled content through Liquid templates.
- Inventory code and templates for strip_html usage and classify whether each use processes untrusted, user-supplied, partner-supplied, or CMS-provided content.
- Add automated tests for newline and carriage-return HTML tag bypasses in template rendering pipelines.
- Deploy or verify context-aware output encoding for all untrusted values, even when a sanitization filter is also used.
- Review Content Security Policy settings to reduce XSS blast radius, especially by avoiding unsafe-inline where feasible.
- Monitor application logs, WAF events, and stored user content for HTML tags containing line breaks plus event-handler attributes.
- If suspicious payloads are found, investigate affected user sessions, administrative actions, content changes, and potential credential or token exposure.
The record
LiquidJS is a Shopify/GitHub Pages compatible template engine written in pure JavaScript. Versions 10.25.7 and below are vulnerable to XSS through a flaw in the strip_html filter logic. The strip_html filter is intended to remove HTML tags from a string before rendering, and is widely used as an XSS sanitizer. The implementation uses a regex whose catch-all branch (<.*?>) does not match line terminators, so any HTML tag containing a \n or \r character passes through unmodified. An attacker who can place a newline inside a tag (e.g. <img\nsrc=x\nonerror=alert(1)>) bypasses sanitization entirely, since browsers treat newlines as whitespace within a tag and execute the resulting onerror/onload/etc. handler. Exploitation is possible for applications that both render attacker-controlled strings via {{ x | strip_html }} to defend against HTML injection and do not separately HTML-escape that output (default behavior — outputEscape is unset by default). This issue has been fixed in version 10.26.0.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | liquidjs | 0 | No fix |
Related vulnerabilities
- GHSA-2qv6-9wx5-cwv4 LiquidJS's strip_html filter bypass via newline characters in HTML tags enables XSS 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
- 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
- GHSA-hh27-hf48-9f5q LiquidJS has a memory and render limit bypass via unbounded width padding in `date`… Also affects liquidjs