如何验证上传的文件是否为视频?

时间:2012-08-07 17:23:53

标签: php php-5.3

我的服务器上有一些非常敏感的信息,因此安全性是个大问题。用户需要能够上传视频。我知道允许用户上传文件会带来安全威胁,因为没有100%的方法可以阻止他们上传非视频。但我显然可以选择服务器将保留哪些文件。

我知道检查文件扩展名是不够的。检查MIME类型更好,但它仍然可以伪造。那么我该如何检查文件是否是视频?

4 个答案:

答案 0 :(得分:9)

玩吧!

唯一可以确定的方法是使用一些代码来解码相关类型的视频,看看它(并检查是否有明智的结果,如非零持续时间)。

否则,您的风险很低:

非恶意场景:

  1. 上传者使用视频/ *内容类型上传视频。
  2. 存储八位字节和内容类型。
  3. 下载程序会下载视频,并使用您收到的内容类型。
  4. 下载器观看视频(或关于编解码器的抱怨等)
  5. 恶意方案1:

    1. 上传者使用视频/ *内容类型上传了一个令人讨厌的木马。
    2. 存储八位字节和内容类型。
    3. 下载程序会下载讨厌的木马,并使用您收到的内容类型。
    4. Downloader在视频播放器中打开令人讨厌的木马。讨厌的木马什么都不做,因为它不是视频。用户抱怨编解码器。更糟糕的情况是,他们在ubuntu论坛上写了关于缺乏对专有格式的支持的咆哮,在你的网页上添加了关于网站如何糟透的评论,因为视频不起作用等等。
    5. 恶意方案2:

      1. Uploader上传了令人讨厌的木马,该木马被写入视频,利用流行视频播放器的一些缓冲区溢出问题。
      2. 你存储......
      3. 下载...
      4. 可能只是上面的一个,但也可能是他们受到攻击(如果他们使用受影响的玩家)。
      5. 有关方案2的三点注意事项:

        1. 测试它是一段视频并不能保证安全,因为它在一些玩家中也可以正常工作。
        2. 如果漏洞位于ffmpeg中,那么测试视频可能会使您的服务器容易受到攻击!
        3. 这种类型的漏洞既罕见又难以做到。一般风险与上传和下载jpegs或png相同。实际上它有点小(这种类型的漏洞确实会影响常用的jpeg库一段时间)。
        4. 总而言之,只需确保只输出您接受的内容类型,并强制文件扩展名匹配它们;如果用户上传名为hahaha.exe的视频/ mpeg,则将其重命名为hahaha.mpg

          编辑:哦,还有:

          恶意方案3:

          上传者以一种使用大量资源的方式上传利用某些玩家的视频。在这种情况下,下载器只会杀死-9 / ctrl-alt-delete /你的操作系统 - 杀死他们所有选择,但如果你的服务器测试它是一个视频,那么它可能会遇到麻烦,因为它有没有人可以介入并杀死200(并且随着剧本小子的剧本不断上传而不断上传)“视频”正试图解释。

          正常进行正常的视频处理可能足以向你介绍DoS的能力(毕竟视频处理相对较重),因此测试文件可能会带来比你节省更多的危险。

答案 1 :(得分:2)

用户可以安全地上传任何内容,只要它到达正确的目录并且服务器上没有任何东西试图运行它(如果它应该是视频,那么什么都不会尝试)。除非受害者以某种方式激活它,否则恶意软件无法做任何事情。

答案 2 :(得分:2)

您可以通过php扩展程序调用{​​{1}}:

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

它基本上包装了ffmpeg的输出,然后您可以在php中检查。但是,您应首先使用ffmpeg来熟悉自己,这本身就是一个完整的主题。如果您不想使用该库,可以通过exec自行执行ffmpeg。

另外,我会检查mimetype。您还可以通过JS检查文件输入中的客户端文件(不是在所有浏览器中,这是没有替代真正的验证)。

LG,

FLO

答案 3 :(得分:0)

我同意,除非视频播放器存在可以通过某些损坏的视频文件利用的问题,否则我不会太担心。但是,不一定要出于安全原因,必须检查您拥有的文件是否是视频文件,并且所有文件都有效,您可以执行以下步骤

  1. 在没有参数的文件上运行ffprobe。它将提供有关该文件的一些信息。编解码器,容器,持续时间,帧速率,比特率。
  2. 现在使用-show_packets运行ffprobe。它应该提供有关文件的逐帧信息。您应该获得与第一个命令给出的duration * frame_rate一样多的视频帧。这可以检查,因为有人可能只是给出一个精心设计的标题或文件的初始部分可能是有效的视频(ffmpeg和ffprobe将只测试视频的前几秒来验证其类型)其余部分可能已损坏。
  3. 使用-show_frames运行ffprobe。这将尝试解码每个帧的标头,以确保每个帧都是有效的视频帧。这是一个额外的步骤,因为某个容器只有一个可用于show_packets的表。因此,ffprobe可能只是简单地读取该表,并且它指向的数据可能已损坏。
  4. 现在理论上可能一个文件包含每个帧的所有有效标题但数据错误但没有解码实际内容并在播放器上查看它这是你可以做的最好的事情。而且我会说这很好,而且速度非常快。