From fda83acdea4c1f88d1af45785ca69ef438f2bbe9 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Thu, 5 Mar 2026 22:28:35 -0800 Subject: [PATCH] Fix IDOR for reports --- src/app/api/reports/[reportId]/route.ts | 11 ++++++---- src/permissions/report.ts | 28 +++++++++++++++++++------ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/app/api/reports/[reportId]/route.ts b/src/app/api/reports/[reportId]/route.ts index 1f22c62fe..d3384f7d6 100644 --- a/src/app/api/reports/[reportId]/route.ts +++ b/src/app/api/reports/[reportId]/route.ts @@ -1,7 +1,7 @@ import { parseRequest } from '@/lib/request'; import { json, notFound, ok, unauthorized } from '@/lib/response'; import { reportSchema } from '@/lib/schema'; -import { canDeleteWebsite, canUpdateWebsite, canViewReport } from '@/permissions'; +import { canDeleteReport, canUpdateReport, canViewReport } from '@/permissions'; import { deleteReport, getReport, updateReport } from '@/queries/prisma'; export async function GET(request: Request, { params }: { params: Promise<{ reportId: string }> }) { @@ -41,13 +41,12 @@ export async function POST( return notFound(); } - if (!(await canUpdateWebsite(auth, websiteId))) { + if (!(await canUpdateReport(auth, report))) { return unauthorized(); } const result = await updateReport(reportId, { websiteId, - userId: auth.user.id, type, name, description, @@ -70,7 +69,11 @@ export async function DELETE( const { reportId } = await params; const report = await getReport(reportId); - if (!(await canDeleteWebsite(auth, report.websiteId))) { + if (!report) { + return notFound(); + } + + if (!(await canDeleteReport(auth, report))) { return unauthorized(); } diff --git a/src/permissions/report.ts b/src/permissions/report.ts index 5f9da019f..fec37d8ca 100644 --- a/src/permissions/report.ts +++ b/src/permissions/report.ts @@ -1,6 +1,6 @@ import type { Report } from '@/generated/prisma/client'; import type { Auth } from '@/lib/types'; -import { canViewWebsite } from './website'; +import { canDeleteWebsite, canUpdateWebsite, canViewWebsite } from './website'; export async function canViewReport(auth: Auth, report: Report) { if (auth.user?.isAdmin) { @@ -14,18 +14,34 @@ export async function canViewReport(auth: Auth, report: Report) { return !!(await canViewWebsite(auth, report.websiteId)); } -export async function canUpdateReport({ user }: Auth, report: Report) { - if (!user) { +export async function canUpdateReport(auth: Auth, report: Report) { + if (!auth.user) { return false; } - if (user.isAdmin) { + if (auth.user.isAdmin) { return true; } - return user.id === report.userId; + if (auth.user.id === report.userId) { + return true; + } + + return !!(await canUpdateWebsite(auth, report.websiteId)); } export async function canDeleteReport(auth: Auth, report: Report) { - return canUpdateReport(auth, report); + if (!auth.user) { + return false; + } + + if (auth.user.isAdmin) { + return true; + } + + if (auth.user.id === report.userId) { + return true; + } + + return !!(await canDeleteWebsite(auth, report.websiteId)); }