Skip to content

[Security] Proto-access control bypass via Map Symbol.toStringTag spoofing + HTML escape bypass #2146

@eddieran

Description

@eddieran

Summary

Three security findings in Handlebars.js v5.0.0-alpha.1:

Finding 1: Proto-Access Control Bypass via Fake Map (Medium)

File: lib/handlebars/runtime.js:119-122

lookupProperty completely skips proto-access controls for Map objects. Map detection uses Object.prototype.toString which is spoofable via Symbol.toStringTag:

const fakeMap = { [Symbol.toStringTag]: 'Map', get(key) { return key === 'constructor' ? Function : undefined; } };
// lookupProperty(fakeMap, 'constructor') returns Function, bypassing the blocklist

Fix: Use instanceof Map instead of toString tag check.

Finding 2: HTML Escaping Bypass via toHTML Duck-Typing (Medium)

File: lib/handlebars/utils.js:61-66

escapeExpression treats any object with a toHTML property as SafeString (no instanceof check). Attacker-controlled data with toHTML bypasses HTML escaping in {{}} expressions.

Fix: Use instanceof SafeString check.

Finding 3: AST Injection via Direct AST Input (Medium)

File: lib/handlebars/compiler/compiler.js:476-485

compile() accepts pre-parsed AST objects without structural validation, enabling code injection via crafted AST nodes through the Function() constructor.

Fix: Validate AST structure before compilation.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions