mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-19 22:40:48 -07:00
fix: enforce ownPropertyOnly for inherited array indices (#924)
* fix: enforce ownPropertyOnly for inherited array indices Route array index access (including negative indices, first/last, and the first/last filters) through a shared readArrayElement helper so that ownPropertyOnly hides prototype-inherited array indices, closing the GHSA-fwxr-j5w2-587m bypass. The option's scope (property/index access only, not filter transforms or iteration) is documented on the option. Co-authored-by: Cursor <[email protected]> * fix(filters): invoke Array.prototype methods on unsanitized array values Call built-ins via Array.prototype.<m>.call(...) for values that come from scope (join, compact, concat, slice, where/reject) so an overridden instance method on unsanitized data cannot hijack filter behavior. Methods on freshly-created arrays are left as-is. Co-authored-by: Cursor <[email protected]> * fix(filters): use String.prototype.slice for the string branch of slice Route the non-array branch through String.prototype.slice.call so the slice filter never dispatches through a possibly-overridden instance method, matching the Array.prototype guard. Co-authored-by: Cursor <[email protected]> --------- Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -183,6 +183,21 @@ describe('Context', function () {
|
||||
ctx.push({ foo: Object.create({ bar: 'BAR' }) })
|
||||
return expect(() => ctx.getSync(['foo', 'bar'])).toThrow(/undefined variable: foo.bar/)
|
||||
})
|
||||
it('should return undefined for inherited array indices', function () {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype[0] = 'POLLUTED'
|
||||
try {
|
||||
const a: number[] = []
|
||||
a.length = 1
|
||||
ctx.push({ foo: a })
|
||||
expect(ctx.getSync(['foo', 0])).toEqual(undefined)
|
||||
expect(ctx.getSync(['foo', -1])).toEqual(undefined)
|
||||
expect(ctx.getSync(['foo', 'first'])).toEqual(undefined)
|
||||
expect(ctx.getSync(['foo', 'last'])).toEqual(undefined)
|
||||
} finally {
|
||||
delete (Array.prototype as any)[0]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('.getAll()', function () {
|
||||
|
||||
Reference in New Issue
Block a user