From 22f466fe76d8b751fe0590d578f8bdf305cb9eca Mon Sep 17 00:00:00 2001 From: Martii Date: Fri, 6 May 2016 00:56:49 -0600 Subject: [PATCH] Do some validation on `@downloadURL` for OUJS based URIs * Additional validation on `@name` * Fix trimming in lib model meta `name`... **NOTE** `trim()` is technically ES5.1 and is used elsewhere already... so normalizing on that Post fix for #944 and applies to #432 and #819... also from initial library creation --- controllers/scriptStorage.js | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/controllers/scriptStorage.js b/controllers/scriptStorage.js index 60ce1050e..fdad5d1b4 100644 --- a/controllers/scriptStorage.js +++ b/controllers/scriptStorage.js @@ -743,6 +743,9 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) { var name = null; var thisName = null; var scriptName = null; + var rAnyLocalHost = new RegExp('^(?:openuserjs\.org|oujs\.org' + + (isDev ? '|localhost:' + (process.env.PORT || 8080) : '') + ')'); + var downloadURL = null; var author = null; var collaborators = null; var installName = aUser.name + '/'; @@ -784,7 +787,29 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) { } // Can't install a userscript name ending in a reserved extension - if (/\.min$/.test(scriptName)) { + if (/\.(?:min|user|user\.js|meta)$/.test(scriptName)) { + aCallback(null); + return; + } + + + // `downloadURL` validations + downloadURL = URL.parse(findMeta(aMeta, 'UserScript.downloadURL.0.value')); + + // Shouldn't install a userscript with a downloadURL of meta .user.js + if (rAnyLocalHost.test(downloadURL.host) && + /^\/meta/.test(downloadURL.pathname) && + /\.user\.js$/.test(downloadURL.pathname)) + { + aCallback(null); + return; + } + + // Shouldn't install a userscript with a downloadURL of source .meta.js + if (rAnyLocalHost.test(downloadURL.host) && + /^\/(?:install|src\/scripts)/.test(downloadURL.pathname) && + /\.meta\.js$/.test(downloadURL.pathname)) + { aCallback(null); return; } @@ -817,14 +842,14 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) { }); } } else { - scriptName = cleanFilename(aMeta.replace(/^\s+|\s+$/g, ''), ''); + scriptName = cleanFilename(aMeta.trim(), ''); if (!scriptName) { aCallback(null); return; } - // Can't install a library name ending in a reserved extension - if (/\.(min|user|meta)$/.test(scriptName)) { + // Can't reference a library name ending in a reserved extension + if (/\.(min|user|user\.js|meta)$/.test(scriptName)) { aCallback(null); return; } @@ -843,7 +868,7 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) { } else if (!aScript) { // New script aScript = new Script({ - name: isLibrary ? aMeta : thisName, + name: isLibrary ? aMeta.trim() : thisName, author: aUser.name, installs: 0, rating: 0, @@ -853,7 +878,7 @@ exports.storeScript = function (aUser, aMeta, aBuf, aCallback, aUpdate) { flags: { critical: 0, absolute: 0 }, installName: installName, fork: null, - meta: isLibrary ? { name: aMeta } : aMeta, + meta: isLibrary ? { name: aMeta.trim() } : aMeta, isLib: isLibrary, uses: isLibrary ? null : libraries, _authorId: aUser._id