From e99fe4e9ed42104f83093f76c49d104d4fe5ea45 Mon Sep 17 00:00:00 2001 From: gpascualg Date: Sun, 3 Jul 2016 02:07:43 +0200 Subject: [PATCH] Fix constructor exploit on NodeJS --- lib/_pluginNode.js | 50 ++++++++++++++++++++++++++++++++-------------- package.json | 4 +++- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/_pluginNode.js b/lib/_pluginNode.js index f3daa6f..9f3465b 100644 --- a/lib/_pluginNode.js +++ b/lib/_pluginNode.js @@ -1,18 +1,20 @@ /** * Contains the routines loaded by the plugin process under Node.js - * + * * Initializes the Node.js environment version of the * platform-dependent connection object for the plugin site */ +require('harmony-reflect') + application = {}; connection = {}; /** * Prints error message and its stack - * + * * @param {Object} msg stack provided by error.stack or a message */ var printError = function(msg) { @@ -49,7 +51,7 @@ process.on('message', function(m) { /** * Checks if the given path is remote - * + * * @param {String} path to check * @returns {Boolean} true if path is remote */ @@ -76,7 +78,7 @@ var importScript = function(url) { var run = function(code) { executeNormal(code, url, sCb, fCb); } - + if (isRemote(url)) { loadRemote(url, run, fCb); } else { @@ -109,7 +111,7 @@ var importScriptJailed = function(url) { var run = function(code) { executeJailed(code, url, sCb, fCb); } - + if (isRemote(url)) { loadRemote(url, run, fCb); } else { @@ -128,7 +130,7 @@ var importScriptJailed = function(url) { /** * Executes the given code in the jailed environment, sends the * corresponding message to the application site when succeeded/failed - * + * * @param {String} code to execute */ var execute = function(code) { @@ -147,7 +149,7 @@ var execute = function(code) { /** * Executes the given code in the current environment / scope, runs * the corresponding callback when done - * + * * @param {String} code to execute * @param {String} url of the script (for displaying the stack) * @param {Function} sCb @@ -164,11 +166,30 @@ var executeNormal = function(code, url, sCb, fCb) { } } +function secureObject(obj) { + if (typeof obj == "object" || typeof obj == "function") { + return new Proxy(obj, { + get: function(target, key, receiver) { + if (key === 'constructor') return secureObject(Object); + if (key === '__proto__') return secureObject(Object.prototype); + return secureObject(target[key]); + }, + set: function(target, key, value, receiver) { + target[key] = secureObject(value); + }, + + getPrototypeOf: function(target) { return secureObject(Object.prototye); }, + setPrototypeOf: function(target) { throw new Error('Restricted'); } + }); + } + + return obj; +} /** * Executes the given code in a jailed environment, runs the * corresponding callback when done - * + * * @param {String} code to execute * @param {String} url of the script (for displaying the stack) * @param {Function} sCb @@ -186,7 +207,7 @@ var executeJailed = function(code, url, sCb, fCb) { ]; for (var i = 0; i < expose.length; i++) { - sandbox[expose[i]] = global[expose[i]]; + sandbox[expose[i]] = secureObject(global[expose[i]]); } code = '"use strict";\n'+code; @@ -201,10 +222,10 @@ var executeJailed = function(code, url, sCb, fCb) { /** - * Loads local file and - * + * Loads local file and + * * @param {String} path of the file to read - * + * * @returns {String} file contents */ var loadLocal = function(path) { @@ -215,7 +236,7 @@ var loadLocal = function(path) { /** * Downloads the script by remote url and provides its content as a * string to the callback - * + * * @param {String} url of the remote module to load * @param {Function} sCb success callback * @param {Function} fCb failure callback @@ -262,6 +283,5 @@ var conn = { _messageHandler: function(){}, onDisconnect: function() {} }; - -connection = conn; +connection = conn; diff --git a/package.json b/package.json index c94b5e0..d9ee63b 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,9 @@ "child_process": false }, "main": "lib/jailed.js", - "dependencies": {}, + "dependencies": { + "harmony-reflect": ">=1.4.6" + }, "devDependencies": {}, "optionalDependencies": {}, "engines": {