From 5b95ddbefce655a137dd79f4f9dfc3b3bc5b5cae Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:15:05 +0000 Subject: [PATCH] feat(rate limiter): add custom rule for GET /auth/local and reduce allowance for all GET /auth/* rate limit rules (#2035) --- .../modules/core/services/ratelimiter.ts | 75 +++++++++++-------- utils/helm/speckle-server/values.schema.json | 8 +- utils/helm/speckle-server/values.yaml | 8 +- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/packages/server/modules/core/services/ratelimiter.ts b/packages/server/modules/core/services/ratelimiter.ts index 41769e45f1..8246c2d00f 100644 --- a/packages/server/modules/core/services/ratelimiter.ts +++ b/packages/server/modules/core/services/ratelimiter.ts @@ -29,6 +29,7 @@ export enum RateLimitAction { 'GET /objects/:streamId/:objectId' = 'GET /objects/:streamId/:objectId', 'GET /objects/:streamId/:objectId/single' = 'GET /objects/:streamId/:objectId/single', 'POST /graphql' = 'POST /graphql', + 'GET /auth/local' = 'GET /auth/local', 'GET /auth/azure' = 'GET /auth/azure', 'GET /auth/gh' = 'GET /auth/gh', 'GET /auth/google' = 'GET /auth/google', @@ -178,84 +179,94 @@ export const LIMITS: RateLimiterOptions = { duration: 1 * TIME.minute } }, + 'GET /auth/local': { + regularOptions: { + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute + }, + burstOptions: { + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute + } + }, 'GET /auth/azure': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/gh': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/google': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/oidc': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/azure/callback': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/gh/callback': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/google/callback': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } }, 'GET /auth/oidc/callback': { regularOptions: { - limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '2'), - duration: 1 * TIME.second + limitCount: getIntFromEnv('RATELIMIT_GET_AUTH', '4'), + duration: 10 * TIME.minute }, burstOptions: { - limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '20'), - duration: 1 * TIME.minute + limitCount: getIntFromEnv('RATELIMIT_BURST_GET_AUTH', '10'), + duration: 30 * TIME.minute } } } diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 8746ba0bf0..a7006c1973 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -953,13 +953,13 @@ }, "get_auth": { "type": "number", - "description": "The maximum number of requests that can be made to the Speckle server to authenticate in a moving one second window.", - "default": 2 + "description": "The maximum number of requests that can be made to the Speckle server to authenticate in a moving 10 minute window.", + "default": 4 }, "burst_get_auth": { "type": "number", - "description": "If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the Speckle server to authenticate in a moving one minute window.", - "default": 20 + "description": "If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the Speckle server to authenticate in a moving thirty minute window.", + "default": 10 } } }, diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index 3d44ce72ab..a8939d8458 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -632,10 +632,10 @@ server: post_graphql: 50 ## @param server.ratelimiting.burst_post_graphql If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the GraphQL API in a moving one minute window. burst_post_graphql: 200 - ## @param server.ratelimiting.get_auth The maximum number of requests that can be made to the Speckle server to authenticate in a moving one second window. - get_auth: 2 - ## @param server.ratelimiting.burst_get_auth If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the Speckle server to authenticate in a moving one minute window. - burst_get_auth: 20 + ## @param server.ratelimiting.get_auth The maximum number of requests that can be made to the Speckle server to authenticate in a moving 10 minute window. + get_auth: 4 + ## @param server.ratelimiting.burst_get_auth If the regular limit is exceeded, the limit is increased to the burst limit. This is the maximum number of requests that can be made to the Speckle server to authenticate in a moving thirty minute window. + burst_get_auth: 10 serviceAccount: ## @param server.serviceAccount.create If enabled, a Kubernetes Service Account will be created for this pod. ## This provides additional security by limiting this pod's access to the Kubernetes API and to Secrets on the Kubernetes cluster.