CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-hh27-hf48-9f5q: LiquidJS has a memory and render limit bypass via unbounded width padding in `date` filter (strftime)

highCVSS 7.5CVE-2026-45357
Summary The date filter's strftime implementation parses width specifiers like %9999999d and forwards the captured width unchecked into pad()/padStart() 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. Details date.ts:5-13 only charges memoryLimit for the lengths of the input value, format string, and timezone: export function date (this: FilterImpl, v: string | Date, format?: string, timezoneOffset?: number | string) { const size = ((v as string)?.length ?? 0) + (format?.length ?? 0) + ((timezoneOffset as string)?.length ?? 0) this.context.memoryLimit.use(size) ... return strftime(date, format) } strftime (src/util/strftime.ts:121) then walks the format with rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/. The captured width group is passed directly to padStart: function format (d, match) { const [input, flagStr = '', width, modifier, conversion] = match ... let padWidth = width || padWidths[conversion] || 0 ... return padStart(ret, padWidth, padChar) // strftime.ts:147 } padStart calls pad() in src/util/underscore.ts:153: export function pad (str, length, ch, add) { str = String(str) let n = length - str.length while (n-- > 0) str = add(str, ch) // unbounded loop return str } The loop has no upper bound and never consults this.context.memoryLimit or renderLimit. The pad is also implemented as repeated ch + str string concatenation, which makes the per-byte cost grow with output length and amplifies CPU consumption. Filter arguments accept context-evaluated values (src/template/filter.ts:30-31, evalToken(arg, context)), so any deployment that passes a context value as the date forma

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 7.5
Published
2026-05-27
Last updated
2026-07-09
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-hh27-hf48-9f5q

Exploitation outlook

EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-45357coverage & exploitation statusNVD · CVE.org

More from GitHub Security Advisories