Last active
March 20, 2020 05:45
-
-
Save meredian/4876493b4e19947a3fb3ec3659a73090 to your computer and use it in GitHub Desktop.
First approach to sniffing detector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// Prerequisites: node 8+ | |
// Install: npm install puppeteer | |
const puppeteer = require('puppeteer'); | |
// const Membrane = require('es7-membrane'); | |
function sniffDetector() { | |
const DEBUG = false | |
window.watched = []; | |
window.sniffed = {}; | |
window.nonConfigurable = {}; | |
const log = function(...args) { | |
console.log(JSON.stringify(args, null, 4)); | |
}; | |
const debug = function(...args) { | |
if (DEBUG) { | |
log(...args) | |
} | |
} | |
const setRecursiveSniffer = (obj, objectPath) => { | |
debug("Running recursive sniffer for path: " + objectPath, obj); | |
let propertyNames = new Set(); // new Set(Object.getOwnPropertyNames(obj)); | |
for (const propertyName in obj) { | |
propertyNames.add(propertyName); | |
} | |
Array.from(propertyNames).forEach((propertyName) => { | |
const childPath = objectPath + '.' + propertyName; | |
const child = obj[propertyName]; | |
debug("Inspecting node", {childPath, child}); | |
const childType = Object.prototype.toString.call(child); | |
window.watched.push(childPath); | |
if (childType === '[object Object]' || childType === '[object Array]') { | |
setRecursiveSniffer(child, childPath); | |
} else { | |
let descriptor = Reflect.getOwnPropertyDescriptor(obj, propertyName) || {}; | |
if (descriptor.configurable != false) { | |
['value', 'writable'].forEach((descriptorProp) => { | |
if (Reflect.has(descriptor, descriptorProp)) { | |
Reflect.deleteProperty(descriptor, descriptorProp); | |
} | |
}); | |
descriptor.get = () => { | |
window.sniffed[childPath] = child; | |
return child; | |
} | |
const updated = Reflect.defineProperty(obj, propertyName, descriptor); | |
if (!updated) { | |
throw new Error(`Can't update ${childPath} descriptor`); | |
} | |
} else { | |
console.log(`Non-configurable descriptor for ${childPath}`); | |
window.nonConfigurable[childPath] = child; | |
} | |
} | |
}); | |
debug("Done setting recursive sniffer for path: " + objectPath); | |
}; | |
setRecursiveSniffer(window.navigator, 'window.navigator'); | |
// setRecursiveSniffer(window.document, 'window.document'); | |
} | |
(async () => { | |
const browser = await puppeteer.launch({ | |
args: ['--javascript-harmony'] | |
}); | |
const page = await browser.newPage(); | |
page.on('pageerror', err => console.error('PAGE EXCEPTION OCCURED:', err)); | |
page.on('console', msg => console.log('PAGE LOG:', msg.text())); | |
page.on('error', err => console.error('PAGE ERROR LOG:', err)); | |
try { | |
await page.evaluateOnNewDocument(sniffDetector); | |
// await page.goto('http://example.com', {waitUntil: 'networkidle2'}) | |
await page.goto('https://www.google.com', {waitUntil: 'networkidle2'}); | |
const sniffedData = await page.evaluate(async function () { | |
return { | |
sniffed: this.sniffed, | |
blind: this.nonConfigurable, | |
watched: window.watched, | |
} | |
}); | |
console.log('All watched handlers: ', sniffedData.watched); | |
console.log('Sniffed: ', sniffedData.sniffed); | |
console.log('Failed to set handler (may also be sniffed): ', sniffedData.blind); | |
await browser.close(); | |
} catch (e) { | |
console.log(e); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment