summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2024-12-08 09:46:49 -0500
committerHazelnoot <acomputerdog@gmail.com>2024-12-08 09:46:49 -0500
commit8b091f77ca776c9c7c5279c2f9fa3c41f2958dc3 (patch)
tree53bf330de002b29ee0c9165a92821b5ce8f037ad /packages/backend/src
parentfix NaN from extremely high rate limits (diff)
downloadsharkey-8b091f77ca776c9c7c5279c2f9fa3c41f2958dc3.tar.gz
sharkey-8b091f77ca776c9c7c5279c2f9fa3c41f2958dc3.tar.bz2
sharkey-8b091f77ca776c9c7c5279c2f9fa3c41f2958dc3.zip
check for invalid rate limit inputs
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/server/api/SkRateLimiterService.ts17
1 files changed, 14 insertions, 3 deletions
diff --git a/packages/backend/src/server/api/SkRateLimiterService.ts b/packages/backend/src/server/api/SkRateLimiterService.ts
index 7726edfb31..b3c09d01c2 100644
--- a/packages/backend/src/server/api/SkRateLimiterService.ts
+++ b/packages/backend/src/server/api/SkRateLimiterService.ts
@@ -131,6 +131,10 @@ export class SkRateLimiterService {
};
}
+ if (factor <= 0) {
+ throw new Error(`Rate limit factor is zero or negative: ${factor}`);
+ }
+
if (isLegacyRateLimit(limit)) {
return await this.limitLegacy(limit, actor, factor);
} else {
@@ -149,7 +153,7 @@ export class SkRateLimiterService {
}
// Convert the "max" limit into a leaky bucket with 1 drip / second rate.
- if (limit.max && limit.duration) {
+ if (limit.max != null && limit.duration != null) {
promises.push(
this.limitBucket({
type: 'bucket',
@@ -172,6 +176,9 @@ export class SkRateLimiterService {
}
private async limitMin(limit: LegacyRateLimit & { minInterval: number }, actor: string, factor: number): Promise<LimitInfo | null> {
+ if (limit.minInterval === 0) return null;
+ if (limit.minInterval < 0) throw new Error(`Invalid rate limit ${limit.key}: minInterval is negative (${limit.minInterval})`);
+
const counter = await this.getLimitCounter(limit, actor, 'min');
const minInterval = Math.max(Math.ceil(limit.minInterval / factor), 0);
@@ -205,10 +212,14 @@ export class SkRateLimiterService {
}
private async limitBucket(limit: RateLimit, actor: string, factor: number): Promise<LimitInfo> {
+ if (limit.size < 1) throw new Error(`Invalid rate limit ${limit.key}: size is less than 1 (${limit.size})`);
+ if (limit.dripRate != null && limit.dripRate < 1) throw new Error(`Invalid rate limit ${limit.key}: dripRate is less than 1 (${limit.dripRate})`);
+ if (limit.dripSize != null && limit.dripSize < 1) throw new Error(`Invalid rate limit ${limit.key}: dripSize is less than 1 (${limit.dripSize})`);
+
const counter = await this.getLimitCounter(limit, actor, 'bucket');
const bucketSize = Math.max(Math.ceil(limit.size * factor), 1);
- const dripRate = (limit.dripRate ?? 1000);
- const dripSize = (limit.dripSize ?? 1);
+ const dripRate = Math.ceil(limit.dripRate ?? 1000);
+ const dripSize = Math.ceil(limit.dripSize ?? 1);
// Update drips
if (counter.c > 0) {