This repository was archived by the owner on May 11, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEvilTrap.js
More file actions
120 lines (110 loc) · 4.2 KB
/
Copy pathEvilTrap.js
File metadata and controls
120 lines (110 loc) · 4.2 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const express = require('express');
const EvilTrapCategory = require('./EvilTrapCategory');
/**
* Convert evil trap name to path suitable for express route.
* @param {string} name
* @returns {string} Path suitable for express route
*/
function nameToPath(name) {
// Using encodeURIComponent to ensure valid paths
return `/${encodeURIComponent(name.toLowerCase().replace(new RegExp('\\s', 'g'), '-'))}/`;
}
class EvilTrap {
/**
* @param {string} name - Human readable identifier of trap
* @param {EvilTrapCategory} [category=EvilTrap.CATEGORY.MISC]
* @param {string} [description] - Short info text about the trap
* @param {Object} [bugs] - A map of bug numbers to show alongside the evil trap,
* currently accepts only "firefox" keys.
* @param {boolean} [unlisted = false] - Whether to hide the trap in navigation
*/
constructor(name, category = EvilTrap.CATEGORY.MISC, description, bugs, unlisted = false) {
if (typeof name !== 'string' || name.length === 0) {
throw new Error('"name" is mandatory. Must be non empty string');
}
this.router = express.Router();
this.path = nameToPath(name);
this.name = name;
this.category = category;
this.description = description;
this.bugs = bugs;
this.unlisted = unlisted;
this.srcRef = null;
}
/**
* Configure http routes for evil trap.
* @param {Function} routeBuilder - Function to be called with router object
* @returns {EvilTrap} - Current EvilTrap instance.
* @memberof EvilTrap
*/
routeBuilder(routeBuilder) {
if (!(routeBuilder instanceof Function)) {
throw new Error('Argument "routeBuilder" must be a function');
}
routeBuilder(this.router);
return this;
}
/**
* Add a http route to serve static files.
*
* @param {string} [mountPath='/'] - Where to register the route relative to the trap base route.
* @param {string} sourcePath - Path of folder to be served.
* @returns {EvilTrap} - Current EvilTrap instance.
* @memberof EvilTrap
*/
addStaticRoute(mountPath = '/', sourcePath) {
if (typeof mountPath !== 'string' || mountPath.length === 0) {
throw new Error('Argument "mountPath" must be non empty string');
}
if (typeof sourcePath !== 'string' || sourcePath.length === 0) {
throw new Error('Argument "sourcePath" must be non empty string');
}
this.router.use(mountPath, express.static(sourcePath));
return this;
}
/**
* Add a page which runs a JS payload
* TODO: add support for reading script from JS file (script as path string).
* @param {string|Function} script - Function string or Function to run on page load
* (injected as script tag in body).
* @param {string} [mountPath='/'] - Where to register the route relative to the trap base route.
* @param {string} [pageTitle=this.name] - Title of HTML page.
* @returns {EvilTrap} - Current EvilTrap instance.
* @memberof EvilTrap
*/
addScriptPage(script, mountPath = '/', pageTitle = this.name) {
let scriptStr;
if (typeof script === 'string') {
scriptStr = script;
} else if (script instanceof Function) {
scriptStr = `(${script.toString()})()`;
} else {
throw new Error('Invalid argument "script", expected string or Function');
}
const body = `<html>
<head>
<title>${pageTitle}</title>
</head>
<body>
<script>
${scriptStr}
</script>
</body>
</html>`;
this.routeBuilder((builder) => {
builder.get(mountPath, (req, res) => {
res.set('Content-Type', 'text/html');
res.status(200).send(body);
});
});
return this;
}
}
EvilTrap.CATEGORY = Object.freeze({
DOS: new EvilTrapCategory('DoS', 'Denial of Service: Crashes, freezes or slows the browser.', true),
FULLSCREEN: new EvilTrapCategory('Fullscreen', 'Abuse full-screen to trap or phish the user.'),
PROMPTSPAM: new EvilTrapCategory('Prompt Spam', null, true),
SPOOF: new EvilTrapCategory('Spoofing', null),
MISC: new EvilTrapCategory('Misc'),
});
module.exports = EvilTrap;