Skip to content

fix(upload): derive R2 key extension from content type, not filename - #77

Merged
royalpinto007 merged 2 commits into
AgentPostmortem:mainfrom
waterlemonnn:fix/r2-upload-key-extension
Aug 8, 2026
Merged

fix(upload): derive R2 key extension from content type, not filename#77
royalpinto007 merged 2 commits into
AgentPostmortem:mainfrom
waterlemonnn:fix/r2-upload-key-extension

Conversation

@waterlemonnn

Copy link
Copy Markdown
Contributor

Fixes #44

getPresignedUploadUrl was building the object key from filename.split(".").pop(), so the extension came straight from user input even though contentType is already validated against ALLOWED_TYPES in the presign route. A request with contentType: "image/png" and filename: "x.html" produced a key ending in .html.

Extension is now derived from a contentType -> extension map, falling back to bin for anything unrecognized. The original filename is no longer used for the key at all — kept only as sanitized metadata on the object (Metadata["original-filename"]) in case it's useful later.

Tests in lib/r2/upload.test.ts cover each allowed content type, an unrecognized type, a hostile filename that shouldn't be able to influence the key, and the metadata sanitization.

npx vitest run (105/105), npx tsc --noEmit, and npx eslint all clean.

waterlemonnn and others added 2 commits August 8, 2026 08:59
getPresignedUploadUrl trusted the extension off the user-supplied filename even though contentType is already validated against ALLOWED_TYPES in the presign route. A hostile filename could put an arbitrary extension on a public object key. Map the validated content type to an extension instead, and keep the original filename only as sanitized object metadata.
@royalpinto007
royalpinto007 merged commit c88acef into AgentPostmortem:main Aug 8, 2026
5 checks passed
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Nice work @waterlemonnn, this is merged.

Genuinely helpful change for agentpostmortem.

If this project helps you out, a star helps others find it too.

Happy to see more from you whenever you have the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

R2 object key extension is taken from the user filename instead of the validated content type

2 participants