handlebars
Version:
Handlebars provides the power necessary to let you build semantic templates effectively with no frustration
99 lines (83 loc) • 11.1 kB
JavaScript
;
exports.__esModule = true;
exports.createProtoAccessControl = createProtoAccessControl;
exports.resultIsAllowed = resultIsAllowed;
exports.isPrototypeConstructor = isPrototypeConstructor;
exports.resetLoggedProperties = resetLoggedProperties;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _utils = require('../utils');
var _logger = require('../logger');
var _logger2 = _interopRequireDefault(_logger);
var loggedProperties = Object.create(null);
function createProtoAccessControl(runtimeOptions) {
// Create an object with "null"-prototype to avoid truthy results on
// prototype properties.
var propertyWhiteList = Object.create(null);
// eslint-disable-next-line no-proto
propertyWhiteList['__proto__'] = false;
_utils.extend(propertyWhiteList, runtimeOptions.allowedProtoProperties);
var methodWhiteList = Object.create(null);
methodWhiteList['constructor'] = false;
methodWhiteList['__defineGetter__'] = false;
methodWhiteList['__defineSetter__'] = false;
methodWhiteList['__lookupGetter__'] = false;
methodWhiteList['__lookupSetter__'] = false;
_utils.extend(methodWhiteList, runtimeOptions.allowedProtoMethods);
return {
properties: {
whitelist: propertyWhiteList,
defaultValue: runtimeOptions.allowProtoPropertiesByDefault
},
methods: {
whitelist: methodWhiteList,
defaultValue: runtimeOptions.allowProtoMethodsByDefault
}
};
}
function resultIsAllowed(result, protoAccessControl, propertyName) {
if (typeof result === 'function') {
return checkWhiteList(protoAccessControl.methods, propertyName);
} else {
return checkWhiteList(protoAccessControl.properties, propertyName);
}
}
/**
* Detect a prototype object's own "constructor" back-reference, e.g.
* `Function.prototype.constructor === Function`. Because "constructor" is an
* "own" property of such objects, it would otherwise bypass the prototype-access
* checks and expose dangerous constructors (allowing arbitrary code execution).
*
* Only functions can be constructors, so other values are never treated as one
* and their `prototype` is never read.
*
* @param {*} parent the object the property is being read from
* @param {string} propertyName the property being looked up
* @param {*} result the already-resolved value of `parent[propertyName]`
* @returns {boolean} true if the lookup resolves `parent`'s own constructor
*/
function isPrototypeConstructor(parent, propertyName, result) {
return propertyName === 'constructor' && typeof result === 'function' && parent === result.prototype;
}
function checkWhiteList(protoAccessControlForType, propertyName) {
if (protoAccessControlForType.whitelist[propertyName] !== undefined) {
return protoAccessControlForType.whitelist[propertyName] === true;
}
if (protoAccessControlForType.defaultValue !== undefined) {
return protoAccessControlForType.defaultValue;
}
logUnexpecedPropertyAccessOnce(propertyName);
return false;
}
function logUnexpecedPropertyAccessOnce(propertyName) {
if (loggedProperties[propertyName] !== true) {
loggedProperties[propertyName] = true;
_logger2['default'].log('error', 'Handlebars: Access has been denied to resolve the property "' + propertyName + '" because it is not an "own property" of its parent.\n' + 'You can add a runtime option to disable the check or this warning:\n' + 'See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details');
}
}
function resetLoggedProperties() {
Object.keys(loggedProperties).forEach(function (propertyName) {
delete loggedProperties[propertyName];
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9oYW5kbGViYXJzL2ludGVybmFsL3Byb3RvLWFjY2Vzcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztxQkFBdUIsVUFBVTs7c0JBQ2QsV0FBVzs7OztBQUU5QixJQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXRDLFNBQVMsd0JBQXdCLENBQUMsY0FBYyxFQUFFOzs7QUFHdkQsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDOztBQUU5QyxtQkFBaUIsQ0FBQyxXQUFXLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDdkMsZ0JBQU8saUJBQWlCLEVBQUUsY0FBYyxDQUFDLHNCQUFzQixDQUFDLENBQUM7O0FBRWpFLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUMsaUJBQWUsQ0FBQyxhQUFhLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDdkMsaUJBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUM1QyxpQkFBZSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQzVDLGlCQUFlLENBQUMsa0JBQWtCLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDNUMsaUJBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUM1QyxnQkFBTyxlQUFlLEVBQUUsY0FBYyxDQUFDLG1CQUFtQixDQUFDLENBQUM7O0FBRTVELFNBQU87QUFDTCxjQUFVLEVBQUU7QUFDVixlQUFTLEVBQUUsaUJBQWlCO0FBQzVCLGtCQUFZLEVBQUUsY0FBYyxDQUFDLDZCQUE2QjtLQUMzRDtBQUNELFdBQU8sRUFBRTtBQUNQLGVBQVMsRUFBRSxlQUFlO0FBQzFCLGtCQUFZLEVBQUUsY0FBYyxDQUFDLDBCQUEwQjtLQUN4RDtHQUNGLENBQUM7Q0FDSDs7QUFFTSxTQUFTLGVBQWUsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFO0FBQ3hFLE1BQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFO0FBQ2hDLFdBQU8sY0FBYyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztHQUNqRSxNQUFNO0FBQ0wsV0FBTyxjQUFjLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO0dBQ3BFO0NBQ0Y7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JNLFNBQVMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUU7QUFDbkUsU0FDRSxZQUFZLEtBQUssYUFBYSxJQUM5QixPQUFPLE1BQU0sS0FBSyxVQUFVLElBQzVCLE1BQU0sS0FBSyxNQUFNLENBQUMsU0FBUyxDQUMzQjtDQUNIOztBQUVELFNBQVMsY0FBYyxDQUFDLHlCQUF5QixFQUFFLFlBQVksRUFBRTtBQUMvRCxNQUFJLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSyxTQUFTLEVBQUU7QUFDbkUsV0FBTyx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEtBQUssSUFBSSxDQUFDO0dBQ25FO0FBQ0QsTUFBSSx5QkFBeUIsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO0FBQ3hELFdBQU8seUJBQXlCLENBQUMsWUFBWSxDQUFDO0dBQy9DO0FBQ0QsZ0NBQThCLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDN0MsU0FBTyxLQUFLLENBQUM7Q0FDZDs7QUFFRCxTQUFTLDhCQUE4QixDQUFDLFlBQVksRUFBRTtBQUNwRCxNQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxLQUFLLElBQUksRUFBRTtBQUMzQyxvQkFBZ0IsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDdEMsd0JBQU8sR0FBRyxDQUNSLE9BQU8sRUFDUCxpRUFBK0QsWUFBWSxvSUFDSCxvSEFDMkMsQ0FDcEgsQ0FBQztHQUNIO0NBQ0Y7O0FBRU0sU0FBUyxxQkFBcUIsR0FBRztBQUN0QyxRQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUEsWUFBWSxFQUFJO0FBQ3BELFdBQU8sZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7R0FDdkMsQ0FBQyxDQUFDO0NBQ0oiLCJmaWxlIjoicHJvdG8tYWNjZXNzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5jb25zdCBsb2dnZWRQcm9wZXJ0aWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVByb3RvQWNjZXNzQ29udHJvbChydW50aW1lT3B0aW9ucykge1xuICAvLyBDcmVhdGUgYW4gb2JqZWN0IHdpdGggXCJudWxsXCItcHJvdG90eXBlIHRvIGF2b2lkIHRydXRoeSByZXN1bHRzIG9uXG4gIC8vIHByb3RvdHlwZSBwcm9wZXJ0aWVzLlxuICBjb25zdCBwcm9wZXJ0eVdoaXRlTGlzdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b1xuICBwcm9wZXJ0eVdoaXRlTGlzdFsnX19wcm90b19fJ10gPSBmYWxzZTtcbiAgZXh0ZW5kKHByb3BlcnR5V2hpdGVMaXN0LCBydW50aW1lT3B0aW9ucy5hbGxvd2VkUHJvdG9Qcm9wZXJ0aWVzKTtcblxuICBjb25zdCBtZXRob2RXaGl0ZUxpc3QgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBtZXRob2RXaGl0ZUxpc3RbJ2NvbnN0cnVjdG9yJ10gPSBmYWxzZTtcbiAgbWV0aG9kV2hpdGVMaXN0WydfX2RlZmluZUdldHRlcl9fJ10gPSBmYWxzZTtcbiAgbWV0aG9kV2hpdGVMaXN0WydfX2RlZmluZVNldHRlcl9fJ10gPSBmYWxzZTtcbiAgbWV0aG9kV2hpdGVMaXN0WydfX2xvb2t1cEdldHRlcl9fJ10gPSBmYWxzZTtcbiAgbWV0aG9kV2hpdGVMaXN0WydfX2xvb2t1cFNldHRlcl9fJ10gPSBmYWxzZTtcbiAgZXh0ZW5kKG1ldGhvZFdoaXRlTGlzdCwgcnVudGltZU9wdGlvbnMuYWxsb3dlZFByb3RvTWV0aG9kcyk7XG5cbiAgcmV0dXJuIHtcbiAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICB3aGl0ZWxpc3Q6IHByb3BlcnR5V2hpdGVMaXN0LFxuICAgICAgZGVmYXVsdFZhbHVlOiBydW50aW1lT3B0aW9ucy5hbGxvd1Byb3RvUHJvcGVydGllc0J5RGVmYXVsdFxuICAgIH0sXG4gICAgbWV0aG9kczoge1xuICAgICAgd2hpdGVsaXN0OiBtZXRob2RXaGl0ZUxpc3QsXG4gICAgICBkZWZhdWx0VmFsdWU6IHJ1bnRpbWVPcHRpb25zLmFsbG93UHJvdG9NZXRob2RzQnlEZWZhdWx0XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzdWx0SXNBbGxvd2VkKHJlc3VsdCwgcHJvdG9BY2Nlc3NDb250cm9sLCBwcm9wZXJ0eU5hbWUpIHtcbiAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gY2hlY2tXaGl0ZUxpc3QocHJvdG9BY2Nlc3NDb250cm9sLm1ldGhvZHMsIHByb3BlcnR5TmFtZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNoZWNrV2hpdGVMaXN0KHByb3RvQWNjZXNzQ29udHJvbC5wcm9wZXJ0aWVzLCBwcm9wZXJ0eU5hbWUpO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZWN0IGEgcHJvdG90eXBlIG9iamVjdCdzIG93biBcImNvbnN0cnVjdG9yXCIgYmFjay1yZWZlcmVuY2UsIGUuZy5cbiAqIGBGdW5jdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3IgPT09IEZ1bmN0aW9uYC4gQmVjYXVzZSBcImNvbnN0cnVjdG9yXCIgaXMgYW5cbiAqIFwib3duXCIgcHJvcGVydHkgb2Ygc3VjaCBvYmplY3RzLCBpdCB3b3VsZCBvdGhlcndpc2UgYnlwYXNzIHRoZSBwcm90b3R5cGUtYWNjZXNzXG4gKiBjaGVja3MgYW5kIGV4cG9zZSBkYW5nZXJvdXMgY29uc3RydWN0b3JzIChhbGxvd2luZyBhcmJpdHJhcnkgY29kZSBleGVjdXRpb24pLlxuICpcbiAqIE9ubHkgZnVuY3Rpb25zIGNhbiBiZSBjb25zdHJ1Y3RvcnMsIHNvIG90aGVyIHZhbHVlcyBhcmUgbmV2ZXIgdHJlYXRlZCBhcyBvbmVcbiAqIGFuZCB0aGVpciBgcHJvdG90eXBlYCBpcyBuZXZlciByZWFkLlxuICpcbiAqIEBwYXJhbSB7Kn0gcGFyZW50IHRoZSBvYmplY3QgdGhlIHByb3BlcnR5IGlzIGJlaW5nIHJlYWQgZnJvbVxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5TmFtZSB0aGUgcHJvcGVydHkgYmVpbmcgbG9va2VkIHVwXG4gKiBAcGFyYW0geyp9IHJlc3VsdCB0aGUgYWxyZWFkeS1yZXNvbHZlZCB2YWx1ZSBvZiBgcGFyZW50W3Byb3BlcnR5TmFtZV1gXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgbG9va3VwIHJlc29sdmVzIGBwYXJlbnRgJ3Mgb3duIGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Byb3RvdHlwZUNvbnN0cnVjdG9yKHBhcmVudCwgcHJvcGVydHlOYW1lLCByZXN1bHQpIHtcbiAgcmV0dXJuIChcbiAgICBwcm9wZXJ0eU5hbWUgPT09ICdjb25zdHJ1Y3RvcicgJiZcbiAgICB0eXBlb2YgcmVzdWx0ID09PSAnZnVuY3Rpb24nICYmXG4gICAgcGFyZW50ID09PSByZXN1bHQucHJvdG90eXBlXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrV2hpdGVMaXN0KHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUsIHByb3BlcnR5TmFtZSkge1xuICBpZiAocHJvdG9BY2Nlc3NDb250cm9sRm9yVHlwZS53aGl0ZWxpc3RbcHJvcGVydHlOYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUud2hpdGVsaXN0W3Byb3BlcnR5TmFtZV0gPT09IHRydWU7XG4gIH1cbiAgaWYgKHByb3RvQWNjZXNzQ29udHJvbEZvclR5cGUuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcHJvdG9BY2Nlc3NDb250cm9sRm9yVHlwZS5kZWZhdWx0VmFsdWU7XG4gIH1cbiAgbG9nVW5leHBlY2VkUHJvcGVydHlBY2Nlc3NPbmNlKHByb3BlcnR5TmFtZSk7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gbG9nVW5leHBlY2VkUHJvcGVydHlBY2Nlc3NPbmNlKHByb3BlcnR5TmFtZSkge1xuICBpZiAobG9nZ2VkUHJvcGVydGllc1twcm9wZXJ0eU5hbWVdICE9PSB0cnVlKSB7XG4gICAgbG9nZ2VkUHJvcGVydGllc1twcm9wZXJ0eU5hbWVdID0gdHJ1ZTtcbiAgICBsb2dnZXIubG9nKFxuICAgICAgJ2Vycm9yJyxcbiAgICAgIGBIYW5kbGViYXJzOiBBY2Nlc3MgaGFzIGJlZW4gZGVuaWVkIHRvIHJlc29sdmUgdGhlIHByb3BlcnR5IFwiJHtwcm9wZXJ0eU5hbWV9XCIgYmVjYXVzZSBpdCBpcyBub3QgYW4gXCJvd24gcHJvcGVydHlcIiBvZiBpdHMgcGFyZW50LlxcbmAgK1xuICAgICAgICBgWW91IGNhbiBhZGQgYSBydW50aW1lIG9wdGlvbiB0byBkaXNhYmxlIHRoZSBjaGVjayBvciB0aGlzIHdhcm5pbmc6XFxuYCArXG4gICAgICAgIGBTZWUgaHR0cHM6Ly9oYW5kbGViYXJzanMuY29tL2FwaS1yZWZlcmVuY2UvcnVudGltZS1vcHRpb25zLmh0bWwjb3B0aW9ucy10by1jb250cm9sLXByb3RvdHlwZS1hY2Nlc3MgZm9yIGRldGFpbHNgXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRMb2dnZWRQcm9wZXJ0aWVzKCkge1xuICBPYmplY3Qua2V5cyhsb2dnZWRQcm9wZXJ0aWVzKS5mb3JFYWNoKHByb3BlcnR5TmFtZSA9PiB7XG4gICAgZGVsZXRlIGxvZ2dlZFByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgfSk7XG59XG4iXX0=