Skip to content

fix(media): ignore inherited prototype keys in the MIME allow-list#46

Open
zqxuii wants to merge 1 commit into
moshcoder:masterfrom
zqxuii:fix/media-proto-mime
Open

fix(media): ignore inherited prototype keys in the MIME allow-list#46
zqxuii wants to merge 1 commit into
moshcoder:masterfrom
zqxuii:fix/media-proto-mime

Conversation

@zqxuii

@zqxuii zqxuii commented Jul 21, 2026

Copy link
Copy Markdown

What

mediaTypeForUpload gated the allow-list with ALLOWED_TYPES[mime] (a truthy bracket lookup). Because that resolves through the prototype chain, a Content-Type of constructor or __proto__ returns an inherited Object.prototype member (truthy), so the function returned that string as an accepted type.

Why it matters

app/api/media/route.ts accepts the upload whenever mediaTypeForUpload(file.name, file.type) is non-null, and file.type is attacker-controlled. So:

  • POST /api/media with a file part whose Content-Type: constructor passes the if (!type) guard and slips any file (e.g. evil.html) past the mp4/webm/mov allow-list.
  • The subsequent ALLOWED_TYPES[type] (= ALLOWED_TYPES["constructor"]) returns the Object function, which then coerces into a garbage stored filename.

Fix

Gate on Object.hasOwn(ALLOWED_TYPES, mime) instead of a truthy bracket lookup — inherited keys no longer match. Legit types and extension inference are unchanged.

Tests

Added a case asserting constructor / __proto__ / hasOwnProperty content-types return null. node --test tests/media-upload-type.test.mjs passes; no other tests affected.

mediaTypeForUpload gated on `ALLOWED_TYPES[mime]` (a truthy bracket lookup), so
a Content-Type of "constructor" or "__proto__" resolved to an inherited
Object.prototype member and returned truthy. The media upload route accepts the
file whenever this returns non-null, so a crafted Content-Type slipped any file
(e.g. evil.html) past the mp4/webm/mov allow-list. Gate on Object.hasOwn; add tests.
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.

1 participant