fix(security): Phase 1 P0 hardening from cross-project audit
Close open uploads, image-proxy SSRF, fail-open AI quotas in production, auth gaps on app routes, and MCP tenant isolation issues. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
37
memento-note/lib/upload-access.ts
Normal file
37
memento-note/lib/upload-access.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { prisma } from './prisma'
|
||||
|
||||
/** Whether a note image upload may be served to the current viewer. */
|
||||
export async function canAccessUploadedNoteImage(
|
||||
filename: string,
|
||||
userId: string | null | undefined,
|
||||
): Promise<boolean> {
|
||||
const imagePath = `/uploads/notes/${filename}`
|
||||
|
||||
const published = await prisma.note.findFirst({
|
||||
where: {
|
||||
isPublic: true,
|
||||
trashedAt: null,
|
||||
OR: [
|
||||
{ content: { contains: imagePath } },
|
||||
{ images: { contains: filename } },
|
||||
],
|
||||
},
|
||||
select: { id: true },
|
||||
})
|
||||
if (published) return true
|
||||
|
||||
if (!userId) return false
|
||||
|
||||
const owned = await prisma.note.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
trashedAt: null,
|
||||
OR: [
|
||||
{ content: { contains: imagePath } },
|
||||
{ images: { contains: filename } },
|
||||
],
|
||||
},
|
||||
select: { id: true },
|
||||
})
|
||||
return !!owned
|
||||
}
|
||||
Reference in New Issue
Block a user