209 lines
6.6 KiB
JavaScript
209 lines
6.6 KiB
JavaScript
describe('security issues', function() {
|
|
describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
|
|
it('should not allow constructors to be accessed', function() {
|
|
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
|
|
.withInput({})
|
|
.toCompileTo('');
|
|
|
|
expectTemplate('{{constructor.name}}')
|
|
.withInput({})
|
|
.toCompileTo('');
|
|
});
|
|
|
|
it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() {
|
|
expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
|
|
.withInput({})
|
|
.withHelper('list', function(element) {
|
|
return [element];
|
|
})
|
|
.toCompileTo('');
|
|
});
|
|
|
|
it('should allow the "constructor" property to be accessed if it is enumerable', function() {
|
|
shouldCompileTo(
|
|
'{{constructor.name}}',
|
|
{
|
|
constructor: {
|
|
name: 'here we go'
|
|
}
|
|
},
|
|
'here we go'
|
|
);
|
|
shouldCompileTo(
|
|
'{{lookup (lookup this "constructor") "name"}}',
|
|
{
|
|
constructor: {
|
|
name: 'here we go'
|
|
}
|
|
},
|
|
'here we go'
|
|
);
|
|
});
|
|
|
|
it('should allow the "constructor" property to be accessed if it is enumerable', function() {
|
|
shouldCompileTo(
|
|
'{{lookup (lookup this "constructor") "name"}}',
|
|
{
|
|
constructor: {
|
|
name: 'here we go'
|
|
}
|
|
},
|
|
'here we go'
|
|
);
|
|
});
|
|
|
|
it('should allow prototype properties that are not constructors', function() {
|
|
function TestClass() {}
|
|
|
|
Object.defineProperty(TestClass.prototype, 'abc', {
|
|
get: function() {
|
|
return 'xyz';
|
|
}
|
|
});
|
|
|
|
shouldCompileTo(
|
|
'{{#with this as |obj|}}{{obj.abc}}{{/with}}',
|
|
new TestClass(),
|
|
'xyz'
|
|
);
|
|
shouldCompileTo(
|
|
'{{#with this as |obj|}}{{lookup obj "abc"}}{{/with}}',
|
|
new TestClass(),
|
|
'xyz'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
|
|
if (!Handlebars.compile) {
|
|
return;
|
|
}
|
|
|
|
describe('without the option "allowExplicitCallOfHelperMissing"', function() {
|
|
it('should throw an exception when calling "{{helperMissing}}" ', function() {
|
|
shouldThrow(function() {
|
|
var template = Handlebars.compile('{{helperMissing}}');
|
|
template({});
|
|
}, Error);
|
|
});
|
|
it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
|
|
shouldThrow(function() {
|
|
var template = Handlebars.compile(
|
|
'{{#helperMissing}}{{/helperMissing}}'
|
|
);
|
|
template({});
|
|
}, Error);
|
|
});
|
|
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
|
var functionCalls = [];
|
|
expect(function() {
|
|
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
|
template({
|
|
fn: function() {
|
|
functionCalls.push('called');
|
|
}
|
|
});
|
|
}).to.throw(Error);
|
|
expect(functionCalls.length).to.equal(0);
|
|
});
|
|
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
|
|
shouldThrow(function() {
|
|
var template = Handlebars.compile(
|
|
'{{#blockHelperMissing .}}{{/blockHelperMissing}}'
|
|
);
|
|
template({
|
|
fn: function() {
|
|
return 'functionInData';
|
|
}
|
|
});
|
|
}, Error);
|
|
});
|
|
});
|
|
|
|
describe('with the option "allowCallsToHelperMissing" set to true', function() {
|
|
it('should not throw an exception when calling "{{helperMissing}}" ', function() {
|
|
var template = Handlebars.compile('{{helperMissing}}');
|
|
template({}, { allowCallsToHelperMissing: true });
|
|
});
|
|
it('should not throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
|
|
var template = Handlebars.compile(
|
|
'{{#helperMissing}}{{/helperMissing}}'
|
|
);
|
|
template({}, { allowCallsToHelperMissing: true });
|
|
});
|
|
it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
|
|
var functionCalls = [];
|
|
var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
|
|
template(
|
|
{
|
|
fn: function() {
|
|
functionCalls.push('called');
|
|
}
|
|
},
|
|
{ allowCallsToHelperMissing: true }
|
|
);
|
|
equals(functionCalls.length, 1);
|
|
});
|
|
it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
|
|
var template = Handlebars.compile(
|
|
'{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
|
|
);
|
|
template({}, { allowCallsToHelperMissing: true });
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('GH-1563', function() {
|
|
it('should not allow to access constructor after overriding via __defineGetter__', function() {
|
|
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
|
|
return this.skip(); // Browser does not support this exploit anyway
|
|
}
|
|
expectTemplate(
|
|
'{{__defineGetter__ "undefined" valueOf }}' +
|
|
'{{#with __lookupGetter__ }}' +
|
|
'{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
|
|
'{{constructor.name}}' +
|
|
'{{/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('');
|
|
});
|
|
});
|
|
});
|