• I am trying to prevent contributors on my site from uploading anything but jpg, png, and gif files. I would prefer that they not even be able to select other file types in the file dialogs. I have created a filter using upload_mimes and it is working, but it seems to be implemented differently based on which Add Media button is clicked. Here is what I am seeing:

    From the Media Library, if I display the files in grid view and click Add New, a file uploader appears above the grid. When I click Select Files, the file dialog only allows me to select my filtered file types — jpg, png, and gif. All other file types are greyed out. This is perfect and exactly what I want.

    If I display the files in list view and click Add New, or click Add New in the left menu, I am taken to a different Upload New Media page. When I click Select Files, the file dialog is not filtered and all file types can be selected.

    For both of these examples, I’m using the multi-file uploader. However, the browser uploader also does not filter the file types in the file dialog.

    Finally, when creating / editing a post, clicking on the Add Media button opens the Add Media dialog. Selecting files here also filters correctly and greys out all other file types.

    Additionally, the grid view and post uploaders also work correctly for files that are dragged and dropped — meaning the file type is checked and an error is displayed before the file is uploaded. The list view, left menu, and browser uploader do not check for file type errors until after the file has been uploaded.

    I guess my question is, why the inconsistency? Is this a known issue? IMHO, the list view and left menu — which both lead to the Upload New Media page — should work the same as the grid view and post uploaders. Are there any plans to standardize how the different uploaders work?

    Thanks!

Viewing 7 replies - 1 through 7 (of 7 total)
  • The file dialog is going to be browser + OS specific, not something that should be controlled by WordPress ( which I’m not even sure it can be… ). I don’t see it as an inconsistency. The main thing is that the mimetype is rejected by WordPress when the user tries to upload it – so as far as I can tell what you’ve described is working as expected.

    The New Media screen and the Add Media Modal window ( on single posts ) are 2 different experiences which is why they’re handled a bit differently but ultimately the same.

    What’s the problem you’re trying to fix? Why do you think something needs to be standardized here?

    Thread Starter jkilbride

    (@jkilbride)

    The problem I’m trying to fix is to avoid uploading files that shouldn’t be uploaded in the first place. If WordPress has the ability to prevent uploads at the browser — which it obviously does, because it works that way in some instances — then it should do so. It’s a waste of time, bandwidth, and server resources to allow files to be uploaded, only to have them throw an error once they reach the server. And since some of the file dialogs already respect the upload_mimes filter, it should be straightforward to add this functionality to all of them.

    While I understand that the file dialog is browser + OS specific, I am not changing my browser and OS when testing this stuff. So, with the same browser and OS, the file dialog interface is different on different pages in the admin. That’s pretty much the definition of inconsistent. Also, I wouldn’t characterize the interfaces as only being a bit different. One prevents uploads from happening for disallowed mime-types. The other uploads the file and then tasks the server with rejecting disallowed mime-types. From a software / programming perspective, that’s a big difference.

    Finally, standardization is good. Why wouldn’t you want these interfaces to be standardized? It’s confusing otherwise. When I setup my upload_mimes filter and tested it for the first time, it seemed to work great. The only file types I was able to select in the file dialog were those that I had allowed. Later, when I tried uploading from a different interface, I was able to select all file types. I had to think to myself, “Wait a second… that worked differently before. What’s going on?” I thought maybe I had done something wrong. After that, I went through each different way a file could be uploaded to the Media Library and found the inconsistencies I detailed above. If all the uploading interfaces worked the same (at least, for the same OS and browser combinations), we could avoid that type of confusion for other people.

    No matter what the file gets uploaded to the servers temp folder and tested on. It’s not reliable to test a files extension from a scripting/browser standpoint because it can be spoofed. You can make a PHP file look like a .jpg until it’s called upon where it runs the PHP inside. Once an error is found ( which as it sounds like you’ve said above, WordPress finds that the mime is not support and discards it ) it’s cleaned up. I believe that when you say: “because it works that way in some instances” in regards to the browser handling uploads, it just looks that way. In reality WordPress is creating an AJAX process talking to the server where the upload is and returning information on the validity of the file.

    The attachments filter select box may show mime-types that you’ve removed but I think there are other hooks for that. If you want more consistency between those filters and the upload_mimes filter that might be a discussion to bring up on trac.

    Thread Starter jkilbride

    (@jkilbride)

    If the file can’t be selected in the file dialog, then it’s certainly not “uploaded to the servers temp folder and tested on.” Also, “[i]n reality WordPress is creating an AJAX process talking to the server where the upload is and returning information on the validity of the file” — I don’t know where you’re getting this. Can you point to a code example where this actually happens? Again, if you can’t select the file in the file dialog, how does WordPress test it’s validity with the server?

    Overall, I think you’re missing my point.

    1. I’m not suggesting files that are uploaded should not be tested on the server. That would be dumb. All I’m saying is that files that can be filtered out in the browser by extension or mime type, should be filtered out in the browser.
    2. I’m aiming this at the typical WordPress user, not at someone who is actively trying to spoof an upload. People spoofing uploads is the reason why you would never remove the file checking done by the server.
    3. If there are other hooks for handling file upload mime types, I haven’t been able to find them. Every example I’ve seen uses the upload_mimes filter.
    4. The thing that’s frustrating, and the reason I brought this up, is that it does work in some of the file dialogs. Some of the file dialogs respect the upload_mimes filter and only let you select file types that are explicitly allowed. My simple question is: why don’t they all work this way?

    I’m trying to be as clear as possible about this. Maybe it’s not coming across that way. It’s possible that this is the wrong place to bring this up. Maybe it belongs in a bug report or feature request?

    Moderator Samuel Wood (Otto)

    (@otto42)

    www.ads-software.com Admin

    I understand what you’re saying.

    The thing you need to understand is that some of that is legacy code for backwards compatibility, some of it is newer JS code, and thus there is indeed an inconsistency about the use of the plUpload feature which allows you to specify file extensions that can be chosen.

    Note, however, that there’s a few problems with your suggestion:

    1. The browser uploader doesn’t actually restrict you from uploading anything anywhere. This is actually not possible to do. Even where you only see the file types you wanted, you can simply change the “Custom Files” drop-down to “All Files” and pick any file you like.

    2. Even if the uploaders were consistent, for backwards compatibility, the basic uploader which doesn’t use javascript and only uses the normal browser “file” input methods will not have such a filter option available for it.

    3. Browsers can only reliably know extension, not actual mime-types. If I rename a txt to a jpg, then I have bypassed whatever filter you put in place in the browser. The browser is also under the user’s control. A simple couple lines of JS into the console and your “protections” are bypassed.

    So, by and large, because these various uploaders were made at various times, by different people, then yes, they are indeed inconsistent. Making them consistent would be a good idea, and I would suggest that you post such a ticket to the core bug tracker (search first, it may already exist).

    But realistically, if you’re wanting to really do this restriction properly, then relying on the browser is a bad choice. The upload_mimes filter will primarily restrict uploads at the server level, but even it is not 100% reliable in detecting a proper mime-type vs. a simple renamed file.

    If you have the “fileinfo” extension available for PHP, then WordPress will attempt to use it to validate a mime type. For image files, WordPress will also attempt to use the “exif_imagetype” and/or “getimagesize” functions, if they are available to your install. This will prevent non-images from being uploaded on the server-side, if these extensions are available and if they can detect non-image files. But no method of detection is perfect, and they can be fooled. So, make sure you have those various PHP extensions available on your server for maximum coverage.

    Thread Starter jkilbride

    (@jkilbride)

    @otto42:

    Thank you for your reply.

    I completely understand the limitations of browser based implementations like the file upload dialog. I’m not looking at this as a security measure or a foolproof way to stop unwanted files from being uploaded. I’m more concerned about UX/UI and consistency for the users – and not having them upload a large (video) file only to find out it isn’t supported. As I said, anyone who steps around this basic precaution, by selecting “All Files”, or tries to spoof the upload file type will have to be caught by the server. I agree, there’s no way to prevent this.

    However, the normal browser file input does have an “accept” attribute. So, even the basic uploader which doesn’t use javascript should be able to filter files in the same way.

    Thanks for the pointers to the fileinfo extension and getimagesize function. I believe I have those available, but I will double-check.

    I will take a look at posting a ticket to the core bug tracker. I haven’t used Trac or svn in a long time, so I’ll have to play with it. I’m more familiar with git/github. I’ll leave this open for a bit longer and if there are no further replies I will close it.

    I’ve found that not all browsers work with the accept attribute (especially mobile), so that doesn’t solve anything. See CanIUse. And it’s worse for the capture attribute. (capture CanIUse)

    And even using the fileinfo and getimagesize won’t find problems with image files that have had other files copied onto the end of an actual image. There are youtube videos explaining how to do this with a few simple commands on the command line. I think the only way the server can sanitize an image is to use something like a PHP function to copyresampled, so that the fields are created from scratch instead of copied from the uploaded version, but I don’t think that’s what is being done on the server, so you take your chances.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Filtering uploads using upload_mimes’ is closed to new replies.