From 6561f83f2a103617bc378ee0f86982a6af5bee75 Mon Sep 17 00:00:00 2001 From: waleed Date: Fri, 12 Dec 2025 17:02:29 -0800 Subject: [PATCH] fix(cron): reject CRON requests when CRON secret is not set --- apps/sim/app/api/workflows/middleware.ts | 2 +- apps/sim/lib/auth/internal.ts | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/api/workflows/middleware.ts b/apps/sim/app/api/workflows/middleware.ts index 5c1b941865..883e02125c 100644 --- a/apps/sim/app/api/workflows/middleware.ts +++ b/apps/sim/app/api/workflows/middleware.ts @@ -42,7 +42,7 @@ export async function validateWorkflowAccess( } const internalSecret = request.headers.get('X-Internal-Secret') - if (internalSecret === env.INTERNAL_API_SECRET) { + if (env.INTERNAL_API_SECRET && internalSecret === env.INTERNAL_API_SECRET) { return { workflow } } diff --git a/apps/sim/lib/auth/internal.ts b/apps/sim/lib/auth/internal.ts index cba5036dc8..cf354fc957 100644 --- a/apps/sim/lib/auth/internal.ts +++ b/apps/sim/lib/auth/internal.ts @@ -69,6 +69,16 @@ export async function verifyInternalToken( * Returns null if authorized, or a NextResponse with error if unauthorized */ export function verifyCronAuth(request: NextRequest, context?: string): NextResponse | null { + if (!env.CRON_SECRET) { + const contextInfo = context ? ` for ${context}` : '' + logger.warn(`CRON endpoint accessed but CRON_SECRET is not configured${contextInfo}`, { + ip: request.headers.get('x-forwarded-for') ?? request.headers.get('x-real-ip') ?? 'unknown', + userAgent: request.headers.get('user-agent') ?? 'unknown', + context, + }) + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) + } + const authHeader = request.headers.get('authorization') const expectedAuth = `Bearer ${env.CRON_SECRET}` if (authHeader !== expectedAuth) {