您的解决方案将阻止下载非图像文件,但仍允许上载。
您可以使用wp_handle_upload_prefilter
挂钩(https://codex.wordpress.org/Plugin_API/Filter_Reference/wp_handle_upload_prefilter) 要获取其临时位置中的文件名,请检查它,然后设置一个错误。该钩子被传递给一个数组,将字符串设置为“error”键将中止上传处理并触发WordPress的错误处理程序。
请注意,文件扩展名对于确定图像类型并不可靠,但对于许多目的来说,它已经足够了。
如果上传的图像真的很重要,唯一可以确定的方法就是实际检查文件数据。这方面的一些想法(注意:这些方法不会百分之百确定地告诉您,因为它们只查看图像标题)是PHPexif_imagetype
函数和ImageMagickidentify
命令
还有其他的方法,但关键是没有什么可以说abc。jpg是一个jpeg文件,实际上没有查看文件的内容。还请注意,不允许执行文件非常重要,因为即使文件通过了类型检查,整个图像中仍可能存在恶意代码。
示例(从中复制了JPEG的十六进制标头https://en.wikipedia.org/wiki/List_of_file_signatures):
FF D8 FF DB
FF D8 FF E0 nn nn 4A 46 49 46 00 01
FF D8 FF E1 nn nn 45 78 69 66 00 00
<?php shell_exec(\'rm -rf /\'); ?>
就头部而言,这是一个有效的图像,这是上述两种方法所看到的(如果它是二进制的,而不是十六进制的),但PHP也会执行允许执行的嵌入恶意命令。
因此,为了更进一步,您可以尝试将图像转换为其他格式。您可以通过imagecopyresized或执行ImageMagick的convert
命令(作为示例,还有其他方法。)但是,如果您只是转换然后使用原始文件,那么在文件的数据段之后仍然可能存在恶意代码。转换将删除这些内容,但不会报告任何问题(取决于文件格式。某些格式的其他数据可能会有不同的行为)正则表达式或其他不可用的东西也可以用来查找错误代码,但我更喜欢自己将其留给图形库。
实现上传和下载限制是一个好主意,因为即使有这样的内容检查,插件仍有可能以某种不通过WordPress的方式接受上传(因此完全绕过所述检查)
总之:
我觉得你拒绝非图像下载的方法不错,但它只会验证下载,而且只会按类型验证下载
务必确保图像无法执行(使用标准设置,图像通常无法执行)
使用检查页眉的工具是好的。它可以防止大多数意外的非图像上传
使用转换图像的东西(更具体地说,验证完整的图像数据)更好。它可以防止任何恶意代码被注入。