From 26e6f2c46c672e4fa7bc16a92191f0b5e5190e03 Mon Sep 17 00:00:00 2001 From: Boik Date: Sun, 17 Sep 2017 11:27:03 +0800 Subject: [PATCH 1/3] use textContent instead innerHTML to remediateDOM based XSS vulnerbilities --- lib/renderer/content-scripts-injector.js | 39 ++++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/renderer/content-scripts-injector.js b/lib/renderer/content-scripts-injector.js index d26802c8a8e7..d23311d5ec2e 100644 --- a/lib/renderer/content-scripts-injector.js +++ b/lib/renderer/content-scripts-injector.js @@ -5,7 +5,7 @@ const {runInThisContext} = require('vm') // https://developer.chrome.com/extensions/match_patterns const matchesPattern = function (pattern) { if (pattern === '') return true - const regexp = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$') + const regexp = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`) const url = `${location.protocol}//${location.host}${location.pathname}` return url.match(regexp) } @@ -23,12 +23,30 @@ const runContentScript = function (extensionId, url, code) { return compiledWrapper.call(this, context.chrome) } +const runStylesheet = function (url, code) { + const wrapper = `(function (code) { + function init() { + var styleElement = document.createElement('style'); + styleElement.setAttribute('type', 'text/css'); + styleElement.textContent = code; + document.head.append(styleElement); + } + document.addEventListener('DOMContentLoaded', init); + })`; + const compiledWrapper = runInThisContext(wrapper, { + filename: url, + lineOffset: 1, + displayErrors: true, + }); + return compiledWrapper.call(this, code); +} + // Run injected scripts. // https://developer.chrome.com/extensions/content_scripts const injectContentScript = function (extensionId, script) { if (!script.matches.some(matchesPattern)) return - if (script.js) { + if (script.js.length) { for (const {url, code} of script.js) { const fire = runContentScript.bind(window, extensionId, url, code) if (script.runAt === 'document_start') { @@ -41,13 +59,16 @@ const injectContentScript = function (extensionId, script) { } } - if (script.css) { - for (const {code} of script.css) { - process.once('document-end', () => { - var node = document.createElement('style') - node.innerHTML = code - window.document.body.appendChild(node) - }) + if (script.css.length) { + for (const {url, code} of script.css) { + const fire = runStylesheet.bind(window, url, code) + if (script.runAt === 'document_start') { + process.once('document-start', fire) + } else if (script.runAt === 'document_end') { + process.once('document-end', fire) + } else if (script.runAt === 'document_idle') { + document.addEventListener('DOMContentLoaded', fire) + } } } } From d86724f17afab087cedcce1786493d1e526c8ec4 Mon Sep 17 00:00:00 2001 From: Boik Date: Sun, 17 Sep 2017 13:56:22 +0800 Subject: [PATCH 2/3] code improvement --- lib/renderer/content-scripts-injector.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/renderer/content-scripts-injector.js b/lib/renderer/content-scripts-injector.js index d23311d5ec2e..5925b941d5ee 100644 --- a/lib/renderer/content-scripts-injector.js +++ b/lib/renderer/content-scripts-injector.js @@ -14,7 +14,7 @@ const matchesPattern = function (pattern) { const runContentScript = function (extensionId, url, code) { const context = {} require('./chrome-api').injectTo(extensionId, false, context) - const wrapper = `(function (chrome) {\n ${code}\n })` + const wrapper = `((chrome) => {\n ${code}\n })` const compiledWrapper = runInThisContext(wrapper, { filename: url, lineOffset: 1, @@ -24,10 +24,9 @@ const runContentScript = function (extensionId, url, code) { } const runStylesheet = function (url, code) { - const wrapper = `(function (code) { + const wrapper = `((code) => { function init() { - var styleElement = document.createElement('style'); - styleElement.setAttribute('type', 'text/css'); + const styleElement = document.createElement('style'); styleElement.textContent = code; document.head.append(styleElement); } @@ -46,27 +45,27 @@ const runStylesheet = function (url, code) { const injectContentScript = function (extensionId, script) { if (!script.matches.some(matchesPattern)) return - if (script.js.length) { + if (script.js) { for (const {url, code} of script.js) { const fire = runContentScript.bind(window, extensionId, url, code) if (script.runAt === 'document_start') { process.once('document-start', fire) } else if (script.runAt === 'document_end') { process.once('document-end', fire) - } else if (script.runAt === 'document_idle') { + } else { document.addEventListener('DOMContentLoaded', fire) } } } - if (script.css.length) { + if (script.css) { for (const {url, code} of script.css) { const fire = runStylesheet.bind(window, url, code) if (script.runAt === 'document_start') { process.once('document-start', fire) } else if (script.runAt === 'document_end') { process.once('document-end', fire) - } else if (script.runAt === 'document_idle') { + } else { document.addEventListener('DOMContentLoaded', fire) } } From 16499358b348330f1d9895615a65155b53d8cddc Mon Sep 17 00:00:00 2001 From: Boik Date: Sun, 17 Sep 2017 14:09:12 +0800 Subject: [PATCH 3/3] fix lint --- lib/renderer/content-scripts-injector.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/renderer/content-scripts-injector.js b/lib/renderer/content-scripts-injector.js index 5925b941d5ee..5bc41780af94 100644 --- a/lib/renderer/content-scripts-injector.js +++ b/lib/renderer/content-scripts-injector.js @@ -31,13 +31,13 @@ const runStylesheet = function (url, code) { document.head.append(styleElement); } document.addEventListener('DOMContentLoaded', init); - })`; + })` const compiledWrapper = runInThisContext(wrapper, { filename: url, lineOffset: 1, - displayErrors: true, - }); - return compiledWrapper.call(this, code); + displayErrors: true + }) + return compiledWrapper.call(this, code) } // Run injected scripts.