fix(upload): enforce size/type limits and derive storage path server-side#4
Open
eltociear wants to merge 1 commit into
Open
fix(upload): enforce size/type limits and derive storage path server-side#4eltociear wants to merge 1 commit into
eltociear wants to merge 1 commit into
Conversation
…side /api/upload uses the service-role Supabase client (bypasses storage RLS), which src/lib/supabaseAdmin.ts's own doc comment says callers must gate with their own authorization/limits before running. This route had none: no file size cap, no content-type allowlist (the client-reported file.type was trusted directly as contentType), and the storage path came straight from the request body instead of being generated server-side. Anonymous submission is intentional here (visitors upload a logo/screenshot while submitting a new listing, see src/views/Submit.tsx), so this doesn't add auth — but it does close off: - unbounded storage/egress cost from arbitrarily large or numerous uploads (now capped at 5MB per file) - uploading non-image content under an attacker-chosen content-type (now allowlisted to png/jpeg/webp/gif/svg) - a caller picking their own storage key, which could collide with another upload's path (upsert: false would then reject the legitimate one) or be used to write outside the flat filename pattern the frontend generates (path is now always server-derived: timestamp + randomUUID + extension)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3.
/api/uploaduses the service-role Supabase client (bypasses storage RLS) with no size cap, no content-type allowlist, and a storage path taken straight from the request body. Anonymous upload is intentional (it's how a visitor attaches a logo/screenshot while submitting a new listing), so this doesn't add auth — it just closes the resource-abuse gaps:file.type.Date.now()-crypto.randomUUID().ext) instead of accepted from the client, so a direct API call can't collide with/squat another upload's key.Small, focused diff — only
app/api/upload/route.tschanged.