JPG 或 MP4 等媒体文件是否可以在编码过程中包含 <?php 或 <script... 等脚本标签? (他们至少可以靠近)

Can media files like JPG or MP4 natively contain script tags like <?php or <script... as a part of their encoding? (They can get close at least)

我正在 PHP 中编写图像上传程序。它将允许用户在网站上上传 JPG 和 PNG 图像。接下来是 MP4 视频(如链接的图片所示)。最重要的是,我的目标是让这个上传器尽可能安全。

( 作为旁注,如果您有兴趣,上传者目前:

文件内容检查:

例如,很明显,将恶意 PHP 或 Javascript 代码插入 .JPG 或任何其他文件非常容易。因此,我还准备好我的上传者从每个文件的内容中删除所有标签,如“

这似乎解决了一个问题,但它会造成另一个问题吗?例如,此媒体文件(请参阅链接图片)包含“ 可以在同一媒体文件中找到的标签。我提到这个只是为了引导你回答我真正的问题:

是否有什么东西阻止 JPG、PNG 和 MP4 编码器或其他相关程序在文件中生成完整的

如果没有什么可以阻止的,那么我应该找到更好的方法来处理媒体文件中的恶意代码。即使我的去除剂有效,我仍然对“正确”的去除方法感兴趣。

我希望我的问题不会太宽泛,因为我提到了多种文件类型。非常感谢任何帮助。非常感谢。

额外的问题:PDF、WEBM、FLV 和其他常见媒体文件怎么样:它们本身可以包含如此完整的标签吗?

Can media files like JPG or MP4 natively contain script tags like <?php or <script... as a part of their encoding?

不,没有算法或编解码器会故意避免这样的输出。

文字

<?php<style 也可以采用多种编码方式:ASCII、UTF-16、UTF-32……这些都有不同的二进制结果,但它可以解释为文本,就像 PHP 或 HTML 文件可以有任何编码。使用您的方法,您还必须考虑搜索 0xff fe 3c 00 73 00 74 00 79 00 6c 00 65 00 以发现以 UTF-16LE 编码的 <style。现在对大写文本执行相同的操作。

二进制

是的,这样的输出可能是巧合:字节 0x3c 73 74 79 可能是:

  • ASCII 字符 <sty
  • UTF-16LE 字符
  • UTF-16BE字符
  • 32 位(英特尔)整数 2037674812
  • 32 位单数(浮点数)7,932e34
  • DOS 日期 2040-11-20 和时间 14:25:56

一组 32 位整数可以组成 ASCII 或 UTF-16 中的拉丁字母。消费者不应将任何文件的内容过度解释为他想要的内容 - valid PHP code even only needs to begin with <?.

格式

文件大多有一种格式,由负载和附加存储组成,例如元数据。在 JFIF file the actual picture is the payload, while a potential thumbnail, a potential comment or potential Exif, IPTC, XMP or ICC 块中是元数据。有效负载可能包含类似于 ASCII 拉丁字母的字节。在文件格式中也可以出现任何拉丁字母(作为 APP 标记或 JFIF 注释的标识)。在元数据中,任何拉丁字母也可能出现,同样是因为它是文本,或者是巧合。

在一个PNG file each chunk中可以碰巧有四个拉丁字母<? 因为它的32位CRC字段。块不需要专用于存储文本(例如 tEXt),但也可以携带解码器静默忽略的任何数据,因为它不知道如何处理它。并且图片有效负载也可以有信心地具有这样的字节。

WebM and FLV are containers, so not only their formats, but also their streams have multiple chances for such byte combinations - you have to expect VP8, VP9, Vorbis and Opus for WebM and Sorensen Spark, VP6, Screen video, H.264, MP3 and even more for FLV. PDF 可以同时包含二进制和文本,解析起来简直就是一场噩梦。

结论

您不会发现所有看起来像文本的东西和您认为危险的东西,也不会发现任何这些文件格式都不会包含可以解释为文本的东西。我对您如何在不破坏每个文件格式的情况下“删除”此类发现感兴趣。

更好的方法是识别文件格式:首先寻找任何 signature 并在找到一个后进行进一步测试,直到你足够确定你持有的是什么。如果失败,您可以拒绝上传。剩下的永远不会有机会被解释为 PHP 文件,这些文件很容易配置。