fix: add more properties required to be enumerable

- __defineGetter__, __defineSetter__, __lookupGetter__, __proto__
This commit is contained in:
Nils Knappmeier
2019-11-17 21:29:47 +01:00
committed by Nils Knappmeier
parent 886ba86c2f
commit 1988878087
5 changed files with 49 additions and 29 deletions
+20 -9
View File
@@ -142,24 +142,35 @@ HandlebarsTestBench.prototype.withMessage = function(message) {
};
HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
expect(this._compileAndExeute()).to.equal(expectedOutputAsString);
};
// see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
HandlebarsTestBench.prototype.toThrow = function(errorLike, errMsgMatcher, msg) {
var self = this;
expect(function() {
self._compileAndExeute();
}).to.throw(errorLike, errMsgMatcher, msg);
};
HandlebarsTestBench.prototype._compileAndExeute = function() {
var compile = Object.keys(this.partials).length > 0
? CompilerContext.compileWithPartial
: CompilerContext.compile;
var combinedRuntimeOptions = this._combineRuntimeOptions();
var template = compile(this.templateAsString, this.compileOptions);
return template(this.input, combinedRuntimeOptions);
};
HandlebarsTestBench.prototype._combineRuntimeOptions = function() {
var self = this;
var combinedRuntimeOptions = {};
Object.keys(this.runtimeOptions).forEach(function(key) {
combinedRuntimeOptions[key] = self.runtimeOptions[key];
});
combinedRuntimeOptions.helpers = this.helpers;
combinedRuntimeOptions.partials = this.partials;
var template = compile(this.templateAsString, this.compileOptions);
var output = template(this.input, combinedRuntimeOptions);
if (output !== expectedOutputAsString) {
// Error message formatted so that IntelliJ-Idea shows "diff"-button
// https://stackoverflow.com/a/10945655/4251384
throw new AssertError(this.message + '\nexpected:' + expectedOutputAsString + 'but was:' + output);
}
return combinedRuntimeOptions;
};
+21 -3
View File
@@ -114,13 +114,31 @@ describe('security issues', function() {
describe('GH-1563', function() {
it('should not allow to access constructor after overriding via __defineGetter__', function() {
if (({}).__defineGetter__ == null || ({}).__lookupGetter__ == null) {
return; // Browser does not support this exploit anyway
return this.skip(); // Browser does not support this exploit anyway
}
shouldCompileTo('{{__defineGetter__ "undefined" valueOf }}' +
expectTemplate('{{__defineGetter__ "undefined" valueOf }}' +
'{{#with __lookupGetter__ }}' +
'{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
'{{constructor.name}}' +
'{{/with}}', {}, '');
'{{/with}}')
.withInput({})
.toThrow(/Missing helper: "__defineGetter__"/);
});
});
describe('GH-1595', function() {
it('properties, that are required to be enumerable', function() {
expectTemplate('{{constructor}}').withInput({}).toCompileTo('');
expectTemplate('{{__defineGetter__}}').withInput({}).toCompileTo('');
expectTemplate('{{__defineSetter__}}').withInput({}).toCompileTo('');
expectTemplate('{{__lookupGetter__}}').withInput({}).toCompileTo('');
expectTemplate('{{__proto__}}').withInput({}).toCompileTo('');
expectTemplate('{{lookup "constructor"}}').withInput({}).toCompileTo('');
expectTemplate('{{lookup "__defineGetter__"}}').withInput({}).toCompileTo('');
expectTemplate('{{lookup "__defineSetter__"}}').withInput({}).toCompileTo('');
expectTemplate('{{lookup "__lookupGetter__"}}').withInput({}).toCompileTo('');
expectTemplate('{{lookup "__proto__"}}').withInput({}).toCompileTo('');
});
});
});