From 5a67ac8086a7f912fba7a1353352ec3dca2e5df0 Mon Sep 17 00:00:00 2001 From: dmitriylaukhin Date: Fri, 12 Jun 2026 14:18:30 +0500 Subject: [PATCH] Close captcha-bypass and email-abuse vectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Block direct /api/auth/sign-up at the middleware (404): it bypassed the Turnstile/honeypot wrapper. /api/register is unaffected — it invokes auth.handler programmatically, not through HTTP. - Tighten rate limits on send-verification-email and forget-password (3/min/IP): both send emails to arbitrary addresses and shared the loose global 100/min limit. Co-Authored-By: Claude Opus 4.8 --- src/lib/auth.ts | 4 ++++ src/middleware.ts | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/lib/auth.ts b/src/lib/auth.ts index d9888b5..8b26abf 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -54,6 +54,10 @@ export const auth = betterAuth({ // массовый сброс паролей + общие IP (офис/NAT). 10/мин/IP — защита // от брутфорса сохраняется, но терпимо к повторам и опечаткам. "/sign-in/email": { window: 60, max: 10 }, + // Эндпоинты, отправляющие письма на произвольный адрес: глобальный + // лимит 100/мин позволял абузить почтовую репутацию домена. + "/send-verification-email": { window: 60, max: 3 }, + "/forget-password": { window: 60, max: 3 }, }, }, trustedOrigins: [ diff --git a/src/middleware.ts b/src/middleware.ts index d172ab7..57166d3 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -6,6 +6,13 @@ const PUBLIC_ROUTES = ["/login", "/register", "/verify-email", "/forgot-password export function middleware(request: NextRequest) { const { pathname } = request.nextUrl; + // Прямой Better Auth sign-up обходит Turnstile/honeypot-обёртку + // (/api/register) — наружу закрыт. Сама регистрация не страдает: + // /api/register вызывает auth.handler программно, минуя middleware. + if (pathname.startsWith("/api/auth/sign-up")) { + return new NextResponse(null, { status: 404 }); + } + if ( PUBLIC_ROUTES.some((route) => pathname.startsWith(route)) || pathname.startsWith("/_next") ||