Harden admin route visibility: 404 not 403, redirect to /login

- deps.py: get_current_admin returns 404 Not Found for non-superusers instead
  of 403 Forbidden — hides endpoint existence from unauthorised callers
- App.tsx: AdminRoute redirects non-admins to /login instead of /, making
  the route indistinguishable from a non-existent page

Layer 3 (network-level IP restriction via Traefik) tracked in TODO.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curo1305
2026-04-13 18:46:33 +02:00
parent 456681fdfa
commit 87c7cc193a
2 changed files with 6 additions and 3 deletions
+4 -2
View File
@@ -36,8 +36,10 @@ async def get_current_admin(
current_user: User = Depends(get_current_user), current_user: User = Depends(get_current_user),
) -> User: ) -> User:
if not current_user.is_superuser: if not current_user.is_superuser:
# Return 404 instead of 403 — reveals neither the existence of the
# endpoint nor that the caller lacks permission.
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, status_code=status.HTTP_404_NOT_FOUND,
detail="Admin access required", detail="Not found",
) )
return current_user return current_user
+2 -1
View File
@@ -21,7 +21,8 @@ function AdminRoute({ children }: { children: React.ReactNode }) {
if (!token) return <Navigate to="/login" replace />; if (!token) return <Navigate to="/login" replace />;
// Wait for the me query before deciding — prevents a flash redirect // Wait for the me query before deciding — prevents a flash redirect
if (isLoading) return null; if (isLoading) return null;
if (!user?.is_admin) return <Navigate to="/" replace />; // Redirect to /login (not /) so the route appears not to exist
if (!user?.is_admin) return <Navigate to="/login" replace />;
return <>{children}</>; return <>{children}</>;
} }