Skip to content

Commit 42841c4

Browse files
committedFeb 7, 2019
fix: disallow access to the constructor in templates to prevent RCE
This commit fixes a Remote Code Execution (RCE) reported by npm-security. Access to non-enumerable "constructor"-properties is now prohibited by the compiled template-code, because this the first step on the way to creating and execution arbitrary JavaScript code. The vulnerability affects systems where an attacker is allowed to inject templates into the Handlebars setup. Further details of the attack may be disclosed by npm-security. Closes #1267 Closes #1495
1 parent bacd473 commit 42841c4

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed
 

‎lib/handlebars/compiler/javascript-compiler.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ JavaScriptCompiler.prototype = {
1313
// PUBLIC API: You can override these methods in a subclass to provide
1414
// alternative compiled forms for name lookup and buffering semantics
1515
nameLookup: function(parent, name/* , type*/) {
16+
if (name === 'constructor') {
17+
return ['(', parent, '.propertyIsEnumerable(\'constructor\') ? ', parent, '.constructor : undefined', ')'];
18+
}
1619
if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1720
return [parent, '.', name];
1821
} else {

‎spec/security.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
describe('security issues', function() {
2+
describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
3+
it('should not allow constructors to be accessed', function() {
4+
shouldCompileTo('{{constructor.name}}', {}, '');
5+
});
6+
7+
it('should allow the "constructor" property to be accessed if it is enumerable', function() {
8+
shouldCompileTo('{{constructor.name}}', {'constructor': {
9+
'name': 'here we go'
10+
}}, 'here we go');
11+
});
12+
13+
it('should allow prototype properties that are not constructors', function() {
14+
class TestClass {
15+
get abc() {
16+
return 'xyz';
17+
}
18+
}
19+
shouldCompileTo('{{#with this as |obj|}}{{obj.abc}}{{/with}}',
20+
new TestClass(), 'xyz');
21+
});
22+
});
23+
});

0 commit comments

Comments
 (0)
Please sign in to comment.