Skip to content

Instantly share code, notes, and snippets.

@bcaudan
Last active July 27, 2018 13:25
Show Gist options
  • Save bcaudan/b16deed888e3b1daaa269f3c70e2fe2e to your computer and use it in GitHub Desktop.
Save bcaudan/b16deed888e3b1daaa269f3c70e2fe2e to your computer and use it in GitHub Desktop.
detect window properties overriden in the current page
(function () {
const iframe = document.createElement('iframe');
document.head.appendChild(iframe);
const cleanWindow = iframe.contentWindow;
function detect(debug) {
const filteredProperties = Object.getOwnPropertyNames(window)
.filter(isNotCommonProperty)
.filter(isNotBlacklistedProperty)
.filter(hasObjectType(window))
.filter(existInCleanWindow);
if (debug) {
filteredProperties.forEach((property) => {
console.log(property);
console.log(getNotNativeObjectProperties(window)(property));
});
} else {
const result = filteredProperties
.map(getNotNativeObjectProperties(window))
.reduce(flatten, [])
.filter(isNativeInCleanWindow);
if (Array.prototype.toJSON !== "undefined") {
result.push('Array.prototype.toJSON');
}
return result;
}
}
function isNotCommonProperty(k) {
return ["length", "name", "arguments", "caller", "prototype", "toString", "toLocaleString"].indexOf(k) === -1;
}
function isNotBlacklistedProperty(p) {
return ["frames", "self", "window", "parent", "top", "document"].indexOf(p) === -1
}
function existInCleanWindow(p) {
return typeof cleanWindow[p] !== "undefined";
}
function isNativeInCleanWindow(p) {
const [head, ...tailParts] = p.split(".");
const tail = tailParts.join(".");
if (tail) {
return !!cleanWindow[head][tail] && /native code/.test(cleanWindow[head][tail].toString())
}
return !!cleanWindow[head] && /native code/.test(cleanWindow[head].toString())
}
function hasObjectType(parentValue) {
return function (key) {
const value = parentValue[key];
return value !== null && value !== undefined && (typeof value === "object" || typeof value === "function");
}
}
function flatten(acc, element) {
return acc.concat(element);
}
function getNotNativeObjectProperties(parentValue) {
return function (key) {
const value = parentValue[key];
const childrenKeys = Object.getOwnPropertyNames(value)
.filter(isNotCommonProperty)
.filter(hasObjectType(value));
return [key]
.filter(isNotNative(parentValue))
.concat(
childrenKeys
.map(getNotNativeObjectProperties(value))
.reduce(flatten, [])
.map(childKey => `${key}.${childKey}`)
)
}
}
function isNotNative(parent) {
return function (k) {
return !!parent[k]
&& (
!/native code/.test(parent[k].toString) || // some overrides of toString prevent to call it...
!/native code/.test(parent[k].toString())
)
}
}
window.detect = detect;
})()
@bcaudan
Copy link
Author

bcaudan commented Apr 7, 2018

Usage:

detect()

Debug:

detect(true)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment