Fix IDOR for reports

This commit is contained in:
Francis Cao
2026-03-05 22:28:35 -08:00
parent a6c909f3df
commit fda83acdea
2 changed files with 29 additions and 10 deletions
+7 -4
View File
@@ -1,7 +1,7 @@
import { parseRequest } from '@/lib/request'; import { parseRequest } from '@/lib/request';
import { json, notFound, ok, unauthorized } from '@/lib/response'; import { json, notFound, ok, unauthorized } from '@/lib/response';
import { reportSchema } from '@/lib/schema'; import { reportSchema } from '@/lib/schema';
import { canDeleteWebsite, canUpdateWebsite, canViewReport } from '@/permissions'; import { canDeleteReport, canUpdateReport, canViewReport } from '@/permissions';
import { deleteReport, getReport, updateReport } from '@/queries/prisma'; import { deleteReport, getReport, updateReport } from '@/queries/prisma';
export async function GET(request: Request, { params }: { params: Promise<{ reportId: string }> }) { export async function GET(request: Request, { params }: { params: Promise<{ reportId: string }> }) {
@@ -41,13 +41,12 @@ export async function POST(
return notFound(); return notFound();
} }
if (!(await canUpdateWebsite(auth, websiteId))) { if (!(await canUpdateReport(auth, report))) {
return unauthorized(); return unauthorized();
} }
const result = await updateReport(reportId, { const result = await updateReport(reportId, {
websiteId, websiteId,
userId: auth.user.id,
type, type,
name, name,
description, description,
@@ -70,7 +69,11 @@ export async function DELETE(
const { reportId } = await params; const { reportId } = await params;
const report = await getReport(reportId); const report = await getReport(reportId);
if (!(await canDeleteWebsite(auth, report.websiteId))) { if (!report) {
return notFound();
}
if (!(await canDeleteReport(auth, report))) {
return unauthorized(); return unauthorized();
} }
+22 -6
View File
@@ -1,6 +1,6 @@
import type { Report } from '@/generated/prisma/client'; import type { Report } from '@/generated/prisma/client';
import type { Auth } from '@/lib/types'; import type { Auth } from '@/lib/types';
import { canViewWebsite } from './website'; import { canDeleteWebsite, canUpdateWebsite, canViewWebsite } from './website';
export async function canViewReport(auth: Auth, report: Report) { export async function canViewReport(auth: Auth, report: Report) {
if (auth.user?.isAdmin) { if (auth.user?.isAdmin) {
@@ -14,18 +14,34 @@ export async function canViewReport(auth: Auth, report: Report) {
return !!(await canViewWebsite(auth, report.websiteId)); return !!(await canViewWebsite(auth, report.websiteId));
} }
export async function canUpdateReport({ user }: Auth, report: Report) { export async function canUpdateReport(auth: Auth, report: Report) {
if (!user) { if (!auth.user) {
return false; return false;
} }
if (user.isAdmin) { if (auth.user.isAdmin) {
return true; 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) { 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));
} }