All rights to Matteo: https://mmazzarolo.com/blog/2022-02-14-find-what-javascript-variables-are-leaking-into-the-global-scope/ https://gist.github.com/mmazzarolo/4cc6ab1b3f176874336bf1ceb7dff6ef#file-runtime-globals-checker-js
/**
* RuntimeGlobalsChecker
*
* You can use this utility to quickly check what variables have been added (or
* leaked) to the global window object at runtime (by JavaScript code).
* By running this code, the globals checker itself is attached as a singleton
* to the window object as "__runtimeGlobalsChecker__".
* You can check the runtime globals programmatically at any time by invoking
* "window.__runtimeGlobalsChecker__.getRuntimeGlobals()".
*
*/
window.__runtimeGlobalsChecker__ = (function createGlobalsChecker() {
// Globals on the window object set by default by the browser.
// We collect them to then filter them out of from the list of globals (since
// we don't care about them).
// They're populated by "collectBrowserGlobals()" and will contain globals such
// as "location" and "localStorage".
let browserGlobals = [];
// Known globals on the window object that we can safely ignored.
// This list should be populated manually after trial and errors.
const ignoredGlobals = ["__runtimeGlobalsChecker__"];
/**
* Collect the global variables added to the window object by the browser by
* creating a temporary iframe and checking what global variables the browser
* adds on it.
* @returns {string[]} - List of globals added added by the browser
*/
function collectBrowserGlobals() {
const iframe = window.document.createElement("iframe");
iframe.src = "about:blank";
window.document.body.appendChild(iframe);
browserGlobals = Object.keys(iframe.contentWindow);
window.document.body.removeChild(iframe);
return browserGlobals;
}
/**
* Return the list of globals added at runtime (by JavaScript).
* @returns {string[]} - List of globals added at runtime (by JavaScript)
*/
function getRuntimeGlobals() {
// If we haven't collected the browser globals yet, do it now.
if (browserGlobals.length === 0) {
collectBrowserGlobals();
}
// Grab all the globals filtering out variables we don't care about (noise).
const runtimeGlobals = Object.keys(window).filter((key) => {
const isFromBrowser = browserGlobals.includes(key);
const isIgnored = ignoredGlobals.includes(key);
return !isFromBrowser && !isIgnored;
});
return runtimeGlobals;
}
return {
getRuntimeGlobals,
};
})();