fix(amplify-velocity-template): block prototype-chain property access in vtl reference resolver - #14964
Merged
Merged
Conversation
… in vtl reference resolver The VTL reference resolver mapped property, index, and method access directly to JavaScript property lookups with no restriction, which allowed a template to traverse the object prototype chain (for example via constructor or __proto__) and reach the Function constructor. This adds a blocked-property guard that is applied on all three access paths (property, bracket/index, and method call) so that names such as constructor, __proto__, and prototype resolve as an undefined reference and blocked names can never be invoked. Normal data and method access is unaffected. Package build and tests run green (153 passing, 0 failing). --- Prompt: Harden the amplify-velocity-template VTL reference resolver against JavaScript prototype-chain property access (constructor/__proto__/prototype); cut a branch from latest dev, implement, test, and commit.
sarayev
marked this pull request as ready for review
July 24, 2026 13:03
svidgen
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of changes
The VTL reference resolver mapped property, index, and method access in a
template directly onto JavaScript property lookups with no restriction on
which names could be resolved. Because JavaScript objects expose their
internal machinery through the prototype chain, a template could walk from
any context value up to the
Functionconstructor — for example$ctx.constructor.constructor("...")— and from there build and invokearbitrary code, escaping the intended template sandbox.
This change hardens the resolver so that JavaScript-internal, prototype-chain
property names can never be resolved or invoked from a template.
Blocked-property guard in the reference resolver
Adds a single
isBlockedPropertyguard backed by a small list ofprototype-chain names:
constructor,__proto__,prototype,__defineGetter__,__defineSetter__,__lookupGetter__, and__lookupSetter__. The guard is applied consistently to all three accesspaths the resolver supports:
$ctx.constructor)$ctx['constructor'])$ctx.constructor(...))When a template references one of these names it now resolves to an undefined
reference, so it renders as empty (or the literal text under non-silent
reference notation) and can never be called. This closes the path from a
context value to the
Functionconstructor.Backward compatibility
Only these JavaScript-internal names change behavior. Normal data access and
method calls are unaffected —
$ctx.name,$ctx['name'],$str.toUpperCase(),$list.size(), and$map.keySet()all continue towork exactly as before. Real template data has no legitimate need to resolve
prototype-chain properties, so this narrows the resolver's surface without
affecting valid templates.
Issue #, if available
N/A
Description of how you validated changes
Added regression tests in
packages/amplify-velocity-template/tests/references.test.js:constructor/__proto__/prototypeaccess all render empty.(
$!ctx.constructor.constructor("globalThis.__vtlMarker = true").call())renders empty and leaves the global marker unset, proving no code was
executed.
calls (
toUpperCase(),size(),keySet()) still resolve correctly.Ran the full package suite with mocha:
0 failing.
Checklist
yarn testpassesBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.