From d440b7c183875a131946c107a5bd1cccb3b13c81 Mon Sep 17 00:00:00 2001 From: pilcrowOnPaper Date: Sun, 6 Oct 2024 15:31:49 +0900 Subject: [PATCH] add password update rate limit --- src/routes/settings/+page.server.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/routes/settings/+page.server.ts b/src/routes/settings/+page.server.ts index 18c1eec..4b4b447 100644 --- a/src/routes/settings/+page.server.ts +++ b/src/routes/settings/+page.server.ts @@ -23,10 +23,13 @@ import { import { decodeBase64 } from "@oslojs/encoding"; import { get2FARedirect } from "$lib/server/2fa"; import { deleteUserTOTPKey, totpUpdateBucket } from "$lib/server/totp"; +import { ExpiringTokenBucket } from "$lib/server/rate-limit"; import type { Actions, RequestEvent } from "./$types"; import type { SessionFlags } from "$lib/server/session"; +const passwordUpdateBucket = new ExpiringTokenBucket(5, 60 * 30); + export async function load(event: RequestEvent) { if (event.locals.session === null || event.locals.user === null) { return redirect(302, "/login"); @@ -79,6 +82,14 @@ async function updatePasswordAction(event: RequestEvent) { } }); } + if (!passwordUpdateBucket.check(event.locals.session.id, 1)) { + return fail(429, { + password: { + message: "Too many requests" + } + }); + } + const formData = await event.request.formData(); const password = formData.get("password"); const newPassword = formData.get("new_password"); @@ -97,6 +108,14 @@ async function updatePasswordAction(event: RequestEvent) { } }); } + + if (!passwordUpdateBucket.consume(event.locals.session.id, 1)) { + return fail(429, { + password: { + message: "Too many requests" + } + }); + } const passwordHash = getUserPasswordHash(event.locals.user.id); const validPassword = await verifyPasswordHash(passwordHash, password); if (!validPassword) {