From 780eff6c4c2b5585ed55ad608812c455bbe85bf4 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Thu, 13 Jun 2024 16:07:17 +0000 Subject: [PATCH] More security for S3 uploads --- src/routes/api/upload/+server.ts | 38 +++++++++++++++++++++++------ src/routes/settings/+page.server.ts | 1 + 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/routes/api/upload/+server.ts b/src/routes/api/upload/+server.ts index fd0403d..c290cbb 100644 --- a/src/routes/api/upload/+server.ts +++ b/src/routes/api/upload/+server.ts @@ -64,9 +64,38 @@ export async function POST(event: RequestEvent): Promise { "Content-Type": contentType, }; + const allowedBuckets = ["backgrounds", "profile-pics"]; + + if (!allowedBuckets.includes(bucket)) { + return new Response(JSON.stringify({ error: "Invalid bucket name" }), { + status: 400, + headers: { + "Content-Type": "application/json", + }, + }); + } + + // Admin only for backgrounds + if ( + bucket === "backgrounds" && + type == "background" && + event.locals.user.role !== "admin" + ) { + return new Response(JSON.stringify({ error: "Unauthorized" }), { + status: 401, + headers: { + "Content-Type": "application/json", + }, + }); + } + await ensureBucketExists(bucket); - if (event.locals.user?.icon && bucket === "profile-pics") { + if ( + event.locals.user?.icon && + bucket === "profile-pics" && + type === "profile-pic" + ) { const key: string = event.locals.user.icon.split("/").pop() as string; await deleteObject(bucket, key); } @@ -77,13 +106,6 @@ export async function POST(event: RequestEvent): Promise { Buffer.from(fileBuffer) ); - if (bucket === "images" && type && type === "background") { - let res = await db.insert(imagesTable).values({ - url: objectUrl, - type: "background", - }); - } - console.log(`File uploaded to ${objectUrl}`); return new Response(JSON.stringify({ objectUrl }), { diff --git a/src/routes/settings/+page.server.ts b/src/routes/settings/+page.server.ts index 2d5d263..3599f20 100644 --- a/src/routes/settings/+page.server.ts +++ b/src/routes/settings/+page.server.ts @@ -74,6 +74,7 @@ export const actions: Actions = { body: profilePicture, headers: { bucket: "profile-pics", + type: "profile-pic", }, });