From bf73150301e1667c0c7970bc604def52980782ad Mon Sep 17 00:00:00 2001 From: ashim-hq Date: Tue, 21 Apr 2026 23:38:42 +0800 Subject: [PATCH] fix: prevent admin escalation when AUTH_ENABLED=false When auth was disabled, the backend middleware attached the first admin user from the database to every request, and the frontend granted all 12 permissions. This gave every unauthenticated visitor full admin access to user management, settings, teams, branding, and feature installation. Now both layers use role "user" with user-level permissions so tools, files, and pipelines still work without login while admin-only routes correctly return 403. Closes #72 --- apps/api/src/plugins/auth.ts | 16 +++++++--------- apps/web/src/hooks/use-auth.ts | 13 +++---------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/apps/api/src/plugins/auth.ts b/apps/api/src/plugins/auth.ts index 5e0bb056..d2956d77 100644 --- a/apps/api/src/plugins/auth.ts +++ b/apps/api/src/plugins/auth.ts @@ -659,16 +659,14 @@ function isPublicRoute(url: string): boolean { export async function authMiddleware(app: FastifyInstance): Promise { app.addHook("preHandler", async (request: FastifyRequest, reply: FastifyReply) => { - // When auth is disabled, attach the first admin user so requireAuth/requireAdmin pass + // When auth is disabled, attach a synthetic non-admin user so tools work + // but admin-only routes (user management, settings write, etc.) stay locked if (!env.AUTH_ENABLED) { - const adminUser = db.select().from(schema.users).where(eq(schema.users.role, "admin")).get(); - if (adminUser) { - (request as FastifyRequest & { user?: AuthUser }).user = { - id: adminUser.id, - username: adminUser.username, - role: "admin", - }; - } + (request as FastifyRequest & { user?: AuthUser }).user = { + id: "anonymous", + username: "anonymous", + role: "user", + }; return; } diff --git a/apps/web/src/hooks/use-auth.ts b/apps/web/src/hooks/use-auth.ts index 173c2695..f69e78e3 100644 --- a/apps/web/src/hooks/use-auth.ts +++ b/apps/web/src/hooks/use-auth.ts @@ -11,19 +11,12 @@ interface AuthState { permissions: string[]; } -const ALL_PERMISSIONS = [ +const USER_PERMISSIONS = [ "tools:use", "files:own", - "files:all", "apikeys:own", - "apikeys:all", "pipelines:own", - "pipelines:all", "settings:read", - "settings:write", - "users:manage", - "teams:manage", - "branding:manage", ]; export function useAuth() { @@ -51,8 +44,8 @@ export function useAuth() { authEnabled: false, isAuthenticated: true, mustChangePassword: false, - role: "admin", - permissions: ALL_PERMISSIONS, + role: "user", + permissions: USER_PERMISSIONS, }); return; }