Executive brief
LiquidJS is a JavaScript template engine used to render dynamic content in Node.js applications. A flaw in its memory protection mechanism allows attackers to craft malicious template input that bypasses memory limits, allocates unlimited memory, and crashes the entire server process with a single HTTP request. This results in complete denial of service to all users.
Technical details
The vulnerability is a logic error in the memoryLimit enforcement mechanism. When LiquidJS evaluates reverse range expressions (e.g., `(100000000..1)` where low > high), it computes memory usage as `high - low + 1`, yielding a negative value. The Limiter.use() method fails to validate that the count parameter is non-negative, allowing the internal counter to go negative. This negative balance permits subsequent legitimate memory allocations to bypass the configured limit. Combined with V8's cons-string optimization (where repeated string concatenation creates a tree structure consuming minimal memory), an attacker can build a 134MB logical string using only kilobytes. When a filter like `replace` forces V8 to flatten the cons-string into contiguous memory, the allocation request (~268MB) triggers an uncatchable V8 Fatal error that immediately terminates the Node.js process. Attack precondition: the attacker must control the Liquid template source code (e.g., via user-supplied templates in a web application). No patch is currently available.
Affected products
- harttle LiquidJS <=10.24.x
Timeline
- 2026-03-25: disclosed