🧩 The Accept Attribute That Mobile Quietly Treated as a Suggestion
The accept attribute on a file input is documented as a hint to the operating system’s file picker, and mobile browsers take that word ‘hint’ seriously – several mobile file/photo pickers show every file regardless of the accept value, or only partially filter based on broad categories like image/* while ignoring a more specific value like image/png. A form that relies on accept alone to keep users from selecting the wrong file type will let plenty of wrong file types through anyway, silently, on exactly the devices where most uploads actually happen.
🔎 The Problem
<input type="file" accept="image/png, image/jpeg">
<!-- Desktop Chrome/Firefox: file picker filters to roughly the
requested types, as expected.
Several mobile browsers/OS combinations: the picker shows every
photo and file regardless of the accept value, or shows a generic
"Photos" picker that doesn'"'"'t distinguish PNG from HEIC from GIF at
all. A user on one of these devices can select a completely
different file type, and the form has no idea anything unusual
happened until it tries to process the upload later. -->
✅ Fix: Validate the Actual File After Selection, Not Just the Picker Hint
- Checking the selected File object’s type (and ideally its actual magic-byte signature via a small read of the first few bytes, not just the browser-reported MIME type, which can itself be wrong or missing) immediately after selection catches anything the OS picker let through that shouldn’t have been – this validation needs to run regardless of what accept says, since accept was never a guarantee to begin with.
- Server-side validation of the uploaded file’s real content type remains mandatory no matter how thorough the client-side check is – a client-side check is entirely for user experience (an immediate, friendly error instead of waiting for a round trip), never a security or correctness boundary on its own.
- A clear inline error message immediately after an invalid file is selected – naming the accepted types explicitly – compensates for the picker not filtering correctly, since the user still gets fast, specific feedback about what went wrong, even though the picker itself didn’t prevent the wrong selection.
⚠️ Why This Passes Testing on a Desktop Browser
- Desktop file pickers (particularly on Windows and macOS) generally do respect accept reasonably well, so a developer testing exclusively on desktop can reasonably conclude the attribute is doing its job – the gap only appears once real users start uploading from phones, which for an image-upload feature is often the majority of actual traffic.
- Mobile OS file/photo pickers vary meaningfully by platform, browser, and OS version in how strictly they honor accept – there’s no single mobile behavior to test against, which is exactly why relying on it as the only line of defense is fragile in a way that’s hard to fully verify through manual testing alone.
The accept attribute is a request, not a rule – the moment a file actually reaches your server, that’s the first point anyone can be sure what type it really is.
