mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-02 16:45:14 -07:00
fix(security): charge pop filter allocation to memoryLimit (CWE-770)
The `pop` array filter cloned the input via `[...toArray(v)]` without charging `this.context.memoryLimit.use(...)`, bypassing the memoryLimit DoS guard that its sibling filters (shift, unshift, compact, etc.) apply. Mirror `shift` to account for the O(N) allocation. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -88,8 +88,10 @@ export function unshift<T> (this: FilterImpl, v: T[], arg: T): T[] {
|
|||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pop<T> (v: T[]): T[] {
|
export function pop<T> (this: FilterImpl, v: T[]): T[] {
|
||||||
const clone = [...toArray(v)]
|
const array = toArray(v)
|
||||||
|
this.context.memoryLimit.use(array.length)
|
||||||
|
const clone = [...array]
|
||||||
clone.pop()
|
clone.pop()
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ describe('DoS related', function () {
|
|||||||
await expect(liquid.parseAndRender(src, { array, count: 3 })).resolves.toBe('a a a a a a a a')
|
await expect(liquid.parseAndRender(src, { array, count: 3 })).resolves.toBe('a a a a a a a a')
|
||||||
await expect(liquid.parseAndRender(src, { array, count: 100 })).rejects.toThrow('memory alloc limit exceeded, line:1, col:26')
|
await expect(liquid.parseAndRender(src, { array, count: 100 })).rejects.toThrow('memory alloc limit exceeded, line:1, col:26')
|
||||||
})
|
})
|
||||||
|
it('should charge pop allocation to memoryLimit', async () => {
|
||||||
|
const array = Array(1e3).fill(0)
|
||||||
|
const liquid = new Liquid({ memoryLimit: 100 })
|
||||||
|
await expect(liquid.parseAndRender('{{ array | pop | size }}', { array })).rejects.toThrow('memory alloc limit exceeded')
|
||||||
|
})
|
||||||
it('should charge strip_html input length to memoryLimit', () => {
|
it('should charge strip_html input length to memoryLimit', () => {
|
||||||
const liquid = new Liquid({ memoryLimit: 100 })
|
const liquid = new Liquid({ memoryLimit: 100 })
|
||||||
expect(() => liquid.parseAndRenderSync('{{ s | strip_html }}', { s: 'a'.repeat(200) }))
|
expect(() => liquid.parseAndRenderSync('{{ s | strip_html }}', { s: 'a'.repeat(200) }))
|
||||||
|
|||||||
Reference in New Issue
Block a user