Skip to content

Commit 9175fe8

Browse files
authored
Some more needed protection (#1975)
* Libraries will be affected in lockdown atm... first usage. * Not sure visible (graceful) messages are needed but we'll give it a whirl atm. Post #944 #1548 Auto-merge
1 parent 4dad3cc commit 9175fe8

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

libs/muExpress.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function renderFile(aRes, aPath, aOptions) {
3232
aOptions.DNT = aRes.oujsOptions.DNT;
3333
aOptions.hideReminderGDPR = aRes.oujsOptions.hideReminderGDPR;
3434
aOptions.showReminderListLimit = aRes.oujsOptions.showReminderListLimit;
35+
aOptions.showReminderInstallLimit = aRes.oujsOptions.showReminderInstallLimit;
3536

3637
// NOTE: Keep in sync with app.js, user.js, and headerReminders.html
3738
aOptions.showInvalidAuth = aRes.oujsOptions.showInvalidAuth;

routes.js

+49-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ var settings = require('./models/settings.json');
3939
//--
4040
var limiter = process.env.LIMITER_STRING || settings.limiter;
4141

42+
var lockdown = process.env.FORCE_BUSY_UPDATEURL_CHECK === 'true';
43+
4244
// WATCHPOINT: ~60 second poll time in MongoDB
4345
var fudgeMin = 60;
4446
var fudgeSec = 6;
@@ -53,8 +55,49 @@ var installCapLimiter = rateLimit({
5355
windowMs: waitInstallCapMin * 60 * 1000, // n minutes for all stores
5456
max: 50, // limit each IP to n requests per windowMs for memory store or expireTimeMs for mongo store
5557
handler: function (aReq, aRes, aNext, aOptions) {
56-
aRes.header('Retry-After', waitInstallCapMin * 60 + (isDev ? fudgeSec : fudgeMin));
57-
aRes.status(429).send();
58+
if (aReq.rateLimit.current < aReq.rateLimit.limit + 4) {
59+
// Midddlware options
60+
if (!aRes.oujsOptions) {
61+
aRes.oujsOptions = {};
62+
}
63+
64+
aRes.oujsOptions.showReminderInstallLimit = 4 - (aReq.rateLimit.current - aReq.rateLimit.limit);
65+
66+
aNext();
67+
} else if (aReq.rateLimit.current < aReq.rateLimit.limit + 10) {
68+
aRes.header('Retry-After', waitInstallCapMin * 60 + (isDev ? fudgeSec : fudgeMin));
69+
statusCodePage(aReq, aRes, aNext, {
70+
statusCode: 429,
71+
statusMessage: 'Too many requests.',
72+
suppressNavigation: true,
73+
isCustomView: true,
74+
statusData: {
75+
isListView: true,
76+
retryAfter: waitInstallCapMin * 60 + (isDev ? fudgeSec : fudgeMin)
77+
}
78+
});
79+
} else if (aReq.rateLimit.current < aReq.rateLimit.limit + 15) {
80+
aRes.header('Retry-After', waitInstallCapMin * 60 + (isDev ? fudgeSec : fudgeMin));
81+
aRes.status(429).send('Too many requests. Please try again later');
82+
} else if (aReq.rateLimit.current < aReq.rateLimit.limit + 20) {
83+
aRes.header('Retry-After', waitInstallCapMin * 60 + (isDev ? fudgeSec : fudgeMin));
84+
aRes.status(429).send();
85+
} else {
86+
cmd = (isPro && process.env.AUTOBAN ? process.env.AUTOBAN : 'echo SIMULATING INSTALL AUTOBAN') +
87+
' ' + aReq.connection.remoteAddress;
88+
89+
exec(cmd, function (aErr, aStdout, aStderr) {
90+
if (aErr) {
91+
console.error('FAIL INSTALL AUTOBAN', cmd);
92+
// fallthrough
93+
} else {
94+
console.log('INSTALL AUTOBAN', aReq.connection.remoteAddress);
95+
// fallthrough
96+
}
97+
98+
aRes.connection.destroy();
99+
});
100+
}
58101
},
59102
skip: function (aReq, aRes) {
60103
var authedUser = aReq.session.user;
@@ -100,7 +143,7 @@ var installRateLimiter = rateLimit({
100143
skip: function (aReq, aRes) {
101144
var authedUser = aReq.session.user;
102145

103-
if (aReq.params.type === 'libs') {
146+
if (aReq.params.type === 'libs' && !lockdown) {
104147
return true;
105148
}
106149

@@ -277,15 +320,15 @@ var listCapLimiter = rateLimit({
277320
aRes.header('Retry-After', waitListCapMin * 60 + (isDev ? fudgeSec : fudgeMin));
278321
aRes.status(429).send();
279322
} else {
280-
cmd = (isPro && process.env.AUTOBAN ? process.env.AUTOBAN : 'echo SIMULATING AUTOBAN') +
323+
cmd = (isPro && process.env.AUTOBAN ? process.env.AUTOBAN : 'echo SIMULATING LIST AUTOBAN') +
281324
' ' + aReq.connection.remoteAddress;
282325

283326
exec(cmd, function (aErr, aStdout, aStderr) {
284327
if (aErr) {
285-
console.error('FAIL AUTOBAN', cmd);
328+
console.error('FAIL LIST AUTOBAN', cmd);
286329
// fallthrough
287330
} else {
288-
console.log('AUTOBAN', aReq.connection.remoteAddress);
331+
console.log('LIST AUTOBAN', aReq.connection.remoteAddress);
289332
// fallthrough
290333
}
291334

views/includes/headerReminders.html

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
<p><i class="fa fa-fw fa-exclamation-triangle"></i> <b>WARNING:</b> You will reach your list limit in {{showReminderListLimit}} more requests.</p>
5858
</div>
5959
{{/showReminderListLimit}}
60+
{{#showReminderInstallLimit}}
61+
<div class="alert alert-danger small fade in" role="alert">
62+
<p><i class="fa fa-fw fa-exclamation-triangle"></i> <b>WARNING:</b> You will reach your install limit in {{showReminderListLimit}} more requests.</p>
63+
</div>
64+
{{/showReminderInstallLimit}}
6065
{{#showSesssionNoExtend}}
6166
<div class="alert alert-danger alert-dismissible alert-autodismissible small fade in" role="alert">
6267
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>

0 commit comments

Comments
 (0)