Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
HTML

HTML5: Fix a File Input That Silently Ignores Its Accept Attribute on Mobile

- 27.09.26 - ErcanOPAK

🧩 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.

— Frontend Architect

Related posts:

HTML Input Types Behave Differently Across Browsers

HTML5: Use Picture Element for Responsive Images (Better Than srcset)

HTML: Use Data Attributes for Interactive Features

Post Views: 1

Post navigation

CSS: Fix a Container Query That Never Triggers Because of a Missing Containment Property
The AI Prompt That Turns a Lease Renewal Offer Into Terms Worth Pushing Back On

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

October 2026
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  
« Sep    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (973)
  • How to make theater mode the default for Youtube (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (939)
  • Get the First and Last Word from a String or Sentence in SQL (847)
  • How to select distinct rows in a datatable in C# (836)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (624)
  • Add Constraint to SQL Table to ensure email contains @ (590)
  • Average of all values in a column that are not zero in SQL (553)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (526)
  • Find numbers with more than two decimal places in SQL (468)

Recent Posts

  • CSS: Fix a prefers-color-scheme Media Query That Gets Silently Overridden by a Browser Extension’s Forced Dark Mode
  • Git: Fix a Merge Commit That Silently Drops a File Because Both Branches Deleted It Differently
  • HTML5: Fix a Native Lazy-Loading Image That Never Loads Because It Sits Inside a Hidden Tab Until the User Clicks It
  • The AI Prompt That Traces a Null Reference Exception Back to the Exact Line That First Produced the Null
  • The AI Prompt That Turns a Gym Membership Contract’s Fine Print Into a Plain-English List of Cancellation Steps
  • Photoshop: Fix a Color Profile Mismatch That Makes Printed Output Look Nothing Like What You Saw On Screen
  • WordPress: Fix Search Results That Return Pages From a Theme You Deactivated Months Ago
  • Visual Studio: Fix a Test Project That Builds Fine Alone but Fails to Discover Any Tests After a NuGet Restore
  • ASP.NET Core: Fix a File Upload That Times Out on Slow Connections Only Because Kestrel’s Minimum Data Rate Feature Kicked In
  • JavaScript: Fix an Array Destructuring Default Value That Silently Never Applies Because null Was Passed Instead of Undefined

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (973)
  • How to make theater mode the default for Youtube (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (939)
  • Get the First and Last Word from a String or Sentence in SQL (847)
  • How to select distinct rows in a datatable in C# (836)

Recent Posts

  • CSS: Fix a prefers-color-scheme Media Query That Gets Silently Overridden by a Browser Extension’s Forced Dark Mode
  • Git: Fix a Merge Commit That Silently Drops a File Because Both Branches Deleted It Differently
  • HTML5: Fix a Native Lazy-Loading Image That Never Loads Because It Sits Inside a Hidden Tab Until the User Clicks It
  • The AI Prompt That Traces a Null Reference Exception Back to the Exact Line That First Produced the Null
  • The AI Prompt That Turns a Gym Membership Contract’s Fine Print Into a Plain-English List of Cancellation Steps

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com