How do I validate that an uploaded file is a video?

空扰寡人 提交于 2021-01-27 07:28:14

问题


I have a server that has some very sensitive information on it, so security is a big issue. The user needs to be able to upload a video. I know allowing users to upload files poses a security threat because there is no 100% way to keep them from uploading non-videos. But I obviously can choose which files the server will keep.

I know that checking the file-extension won't suffice. Checking the MIME type is better but it can still be faked. So how do I go about checking if the file is a video?


回答1:


Play it!

Only way to be sure is to have some code that decodes videos of the type in question, take a look at it (and check there's sensible results, like a non-zero duration).

Otherwise though, your risks are low:

Non-malicious scenario:

  1. Uploader uploads video, with a video/* content-type.
  2. You store the octets and content-type.
  3. Downloader downloads video, and you use the content-type you received.
  4. Downloader watches video (or grumbles about codecs, etc.)

Malicious scenario 1:

  1. Uploader uploads a nasty trojan, with a video/* content-type.
  2. You store the octets and content-type.
  3. Downloader downloads nasty trojan, and you use the content-type you received.
  4. Downloader opens nasty trojan in video player. Nasty trojan does nothing because it's not a video. User grumbles about codecs. Worse case scenario is, they write rant on ubuntu forums about lack of support for proprietary formats, adds ill-spelt comments on your page about how the site sucks because the video didn't work, etc.

Malicious scenario 2:

  1. Uploader uploads nasty trojan that is written into a video that exploits some buffer-overflow issue with a popular video player.
  2. You store...
  3. Downloader...
  4. Could just be like one of the above, but it could also be that they get hit by the exploit (if they're using the affected player).

Three things to note about scenario 2 though:

  1. Testing it's a video won't guarantee safety, as it could well have also work fine in some players.
  2. Testing it's a video could make your server vulnerable to the exploit, if the vulnerability is in ffmpeg!
  3. Exploits of this type are both rare, and hard to do. The general risk is the same as uploading and downloading jpegs or pngs. Indeed it's a bit smaller (there was indeed an exploit of this type affecting commonly-used jpeg libraries for a while).

In all, just make sure you only output with the content-types you accept, and force file-extensions to match them; if the user uploads a video/mpeg called hahaha.exe, then rename it hahaha.mpg

Edit: Oh, also:

Malicious scenario 3:

Uploader uploads video that exploits some players in a way that uses a lot of resources. In this case a downloader will just kill-9/ctrl-alt-delete/your-OSs-kill-them-all-of-choice, but if your server is testing it's a video, then it could end up in trouble as there's no one on hand to step in and kill the 200 (and growing as the script-kiddies's script keeps uploading more) "videos" it's trying to interpret.

Just doing normal video-processing could be enough to introduce the ability to DoS you (video processing is relatively heavy after all), so testing the file could introduce more dangers than it saves you from.




回答2:


You can call ffmpeg via a php extension:

https://github.com/char0n/ffmpeg-php/

which essentially wraps the output of ffmpeg, which you then can check in php. However, you should familliarize yourself with ffmpeg first, which is a whole topic on its own. If you don't want to use the library, you can execute ffmpeg on your own via exec.

Additionally, I would check the mimetype. You can also check the file on the client side within a file input via JS (not in all browsers and this is no replacement for a true validation).

lg,

flo




回答3:


Users can safely upload anything as long as it goes to the right directory and nothing on the server tries to run it (and if it's supposed to be a video, nothing will try). Malware can't do anything unless the victim somehow activates it.




回答4:


I agree that unless video players have a issue that can be exploited via some corrupted video files I won't worry much. But say for not necessarily security reasons one had to check whether the file you have is a video file and all of it is valid you could execute the following steps

  1. Run ffprobe on the file without arguments. It will give some information about the file. The codecs, containers, duration, frame rate, bitrate.
  2. Now run ffprobe with -show_packets. It should give out frame by frame information about the file. You should get as many video frames as duration*frame_rate given by the first command. This can be checked because someone could just give a crafted header or initial section of the file could be valid video (ffmpeg and ffprobe will only test the first few seconds of the video to verify its type) the rest could be corrupted.
  3. Run ffprobe with -show_frames. This will try and decode headers of each frame to ensure each one is a valid video frame. This is an additional step because some container simply have a table that can be used for show_packets. Hence ffprobe could have simply read that table and the data it is pointing to may be corrupt.

Now it is theoretically possible that a file has all valid headers for every frame but wrong data but without decoding the actual content and viewing it on a player this is the best you can do afaik. And I would say that is good enough and it is very fast.



来源:https://stackoverflow.com/questions/11851016/how-do-i-validate-that-an-uploaded-file-is-a-video

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!