{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata — refreshed continuously.","feed_url":"https://feed.craftedsignal.io/tags/memory-amplification/","home_page_url":"https://feed.craftedsignal.io/","items":[{"_cs_actors":[],"_cs_cves":[],"_cs_exploited":false,"_cs_products":[],"_cs_severities":["critical"],"_cs_tags":["liquidjs","denial-of-service","memory-amplification"],"_cs_type":"advisory","_cs_vendors":[],"content_html":"\u003cp\u003eLiquidJS version 10.24.0 and earlier contains a vulnerability in its \u003ccode\u003ereplace_first\u003c/code\u003e filter that allows for exponential memory amplification. The \u003ccode\u003ereplace_first\u003c/code\u003e filter delegates to JavaScript\u0026rsquo;s native \u003ccode\u003eString.prototype.replace()\u003c/code\u003e, which interprets \u003ccode\u003e$\u0026amp;\u003c/code\u003e as a backreference to the matched substring. The filter only charges the input string length against the configured \u003ccode\u003ememoryLimit\u003c/code\u003e, not the amplified output. An attacker can exploit this by crafting a Liquid template with a replacement string containing multiple repetitions of \u003ccode\u003e$\u0026amp;\u003c/code\u003e, causing the output string to grow exponentially with each replacement. By chaining this technique across multiple variable assignments, an attacker can easily exhaust available memory, leading to a denial-of-service condition. This vulnerability affects applications that render user-provided Liquid templates, such as CMS platforms, newsletter editors, and SaaS platforms.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eThe attacker crafts a malicious Liquid template.\u003c/li\u003e\n\u003cli\u003eThe template uses the \u003ccode\u003ereplace_first\u003c/code\u003e filter with a pattern containing multiple \u003ccode\u003e$\u0026amp;\u003c/code\u003e backreferences. For example: \u003ccode\u003e{% assign s = \u0026quot;A\u0026quot; %}{% assign s = s | replace_first: s, \u0026quot;$\u0026amp;$\u0026amp;$\u0026amp;...(50 times)...$\u0026amp;\u0026quot; %}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe LiquidJS engine parses the template.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003ereplace_first\u003c/code\u003e filter is called.\u003c/li\u003e\n\u003cli\u003eThe filter utilizes the native \u003ccode\u003eString.prototype.replace()\u003c/code\u003e method to perform the replacement.\u003c/li\u003e\n\u003cli\u003eEach instance of \u003ccode\u003e$\u0026amp;\u003c/code\u003e in the replacement string is expanded to the matched substring, causing the output string to grow exponentially.\u003c/li\u003e\n\u003cli\u003eThe expanded string consumes excessive memory, potentially exceeding available resources.\u003c/li\u003e\n\u003cli\u003eThe application crashes or becomes unresponsive, resulting in a denial-of-service condition.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation of this vulnerability can lead to a denial-of-service condition. A single request can allocate hundreds of megabytes of memory, and concurrent requests can cause complete service unavailability. The Node.js event loop is blocked, and legitimate user requests are stalled. Empirical results have demonstrated that with 20 concurrent requests, legitimate users experience up to 13-second delays. Each attack request costs only a few hundred bytes, making it easy to launch a large-scale attack.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eApply a patch to LiquidJS that properly accounts for memory usage when using the \u003ccode\u003ereplace_first\u003c/code\u003e filter with backreferences.\u003c/li\u003e\n\u003cli\u003eAlternatively, disable or remove the \u003ccode\u003ereplace_first\u003c/code\u003e filter entirely and use the \u003ccode\u003ereplace\u003c/code\u003e filter instead, which treats \u003ccode\u003e$\u0026amp;\u003c/code\u003e as a literal string.\u003c/li\u003e\n\u003cli\u003eImplement input validation and sanitization to prevent the use of \u003ccode\u003e$\u0026amp;\u003c/code\u003e backreferences in user-provided Liquid templates.\u003c/li\u003e\n\u003cli\u003eMonitor web server logs for suspicious requests containing Liquid templates with excessive use of the \u003ccode\u003ereplace_first\u003c/code\u003e filter and \u003ccode\u003e$\u0026amp;\u003c/code\u003e patterns using the Sigma rule below.\u003c/li\u003e\n\u003cli\u003eImplement rate limiting to mitigate the impact of denial-of-service attacks.\u003c/li\u003e\n\u003cli\u003eIncrease the \u003ccode\u003ememoryLimit\u003c/code\u003e configuration value to provide a temporary buffer against memory exhaustion, but this will not fully prevent the attack.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-03-25T17:44:23Z","date_published":"2026-03-25T17:44:23Z","id":"/briefs/2024-02-liquidjs-dos/","summary":"The `replace_first` filter in LiquidJS is vulnerable to exponential memory amplification due to its use of JavaScript's `String.prototype.replace()` and mishandling of the `$\u0026` backreference pattern, allowing attackers to bypass the `memoryLimit` and cause denial of service.","title":"LiquidJS replace_first Filter Exponential Memory Amplification DoS","url":"https://feed.craftedsignal.io/briefs/2024-02-liquidjs-dos/"}],"language":"en","title":"CraftedSignal Threat Feed — Memory-Amplification","version":"https://jsonfeed.org/version/1.1"}