4

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

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

4

4 回答 4

9

玩!

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

否则,您的风险很低:

非恶意场景:

  1. Uploader 上传视频,内容类型为 video/*。
  2. 您存储八位字节和内容类型。
  3. 下载器下载视频,您使用收到的内容类型。
  4. 下载者观看视频(或抱怨编解码器等)

恶意场景一:

  1. Uploader 上传一个讨厌的木马,内容类型为 video/*。
  2. 您存储八位字节和内容类型。
  3. 下载器下载讨厌的木马,而您使用您收到的内容类型。
  4. 下载器在视频播放器中打开讨厌的木马。讨厌的木马什么都不做,因为它不是视频。用户抱怨编解码器。更糟糕的情况是,他们在 ubuntu 论坛上发表关于缺乏对专有格式的支持的咆哮,在您的页面上添加关于网站如何因为视频无法正常工作而糟糕的评论等等。

恶意场景2:

  1. Uploader 上传恶意木马,该木马被写入视频,利用流行视频播放器的一些缓冲区溢出问题。
  2. 你存...
  3. 下载器...
  4. 可能只是上述情况之一,但也可能是他们受到了攻击(如果他们正在使用受影响的玩家)。

关于场景 2 需要注意的三件事:

  1. 测试它是一个视频并不能保证安全,因为它很可能在某些播放器中也能正常工作。
  2. 如果漏洞在 ffmpeg 中,测试它是一个视频可能会使您的服务器容易受到攻击!
  3. 这种类型的漏洞利用既罕见又难做。一般风险与上传和下载 jpeg 或 png 相同。实际上它有点小(确实存在这种类型的漏洞利用一段时间影响常用的 jpeg 库)。

总之,只要确保你只输出你接受的内容类型,并强制文件扩展名匹配它们;如果用户上传了一个名为 haha​​ha.exe 的视频/mpeg,则将其重命名为 haha​​ha.mpg

编辑:哦,还有:

恶意场景3:

Uploader 上传的视频以占用大量资源的方式利用某些播放器。在这种情况下,下载器只会 kill-9/ctrl-alt-delete/your-OSs-kill-them-all-of-choice,但是如果您的服务器正在测试它是一个视频,那么它最终可能会遇到麻烦,因为有没有人介入并杀死它试图解释的 200 个(并且随着脚本小子的脚本不断上传更多)“视频”。

仅仅进行正常的视频处理就足以引入 DoS 的能力(毕竟视频处理相对繁重),因此测试文件可能会带来更多的危险,而不是它可以为您节省的风险。

于 2012-08-07T17:36:53.333 回答
2

您可以ffmpeg通过 php 扩展程序调用:

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

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

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

lg,

弗洛

于 2012-08-07T17:35:15.223 回答
1

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

于 2012-08-07T17:32:02.400 回答
0

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

  1. 在不带参数的文件上运行 ffprobe。它将提供有关该文件的一些信息。编解码器、容器、持续时间、帧速率、比特率。
  2. 现在使用 -show_packets 运行 ffprobe。它应该逐帧给出有关文件的信息。您应该获得与第一个命令给出的 duration*frame_rate 一样多的视频帧。可以检查这一点,因为有人可以只提供精心制作的标题或文件的初始部分可能是有效的视频(ffmpeg 和 ffprobe 只会测试视频的前几秒钟以验证其类型),其余部分可能已损坏。
  3. 使用 -show_frames 运行 ffprobe。这将尝试解码每个帧的标头,以确保每个帧都是有效的视频帧。这是一个额外的步骤,因为某些容器只是有一个可用于 show_packets 的表。因此 ffprobe 可以简单地读取该表并且它指向的数据可能已损坏。

现在理论上,一个文件有可能对每一帧都有所有有效的标题,但数据错误,但没有解码实际内容并在播放器上查看它,这是你能做的最好的 afaik。我会说这已经足够好了,而且速度非常快。

于 2012-08-09T07:03:53.027 回答