Skip to content

🔐 Dashboard routes lack per-user authorization checks #313

@spaciousejar

Description

@spaciousejar

Description

While middleware.ts protects dashboard and chatbot routes from unauthenticated access, there are no explicit authorization checks within the page/API logic to verify a user is accessing their own data. This is a classic Insecure Direct Object Reference (IDOR) pattern.

Impact

An authenticated user could potentially access or modify another user's:

  • Period tracking history
  • Chat conversations
  • Personal settings

Existing Guard (Not Enough)

// middleware.ts — this only checks *if* you're logged in, not *whose* data you're accessing
const isProtectedRoute = createRouteMatcher(["/dashboard(.*)", "/chatbot(.*)"]);
export default clerkMiddleware(async (auth, req) => {
  if (isProtectedRoute(req)) await auth.protect();
});

Suggested Fix

In every API route that returns user-specific data, compare the authenticated user ID from Clerk against the resource owner ID:

const { userId } = await auth();
if (!userId || userId !== requestedResource.userId) {
  return Response.json({ error: 'Unauthorized' }, { status: 403 });
}

Severity: MEDIUM | Ref: PCS-003

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions