我想让用户从远程网址复制或下载图像,或从他们的计算机上传文件(可能包括pdfs和txt文件等)。为此,我尝试了file_get_contents并卷曲了我的主机支持的两个。对于本地上传,我只是使用PHP。他们完成了传输数据的基本工作。但是,我试图找到验证文件内容的最佳方法,以避免传播恶意代码或使用过大的文件加载我的服务器。
在许多情况下,文件将动态生成,因此不会以已知的扩展名结束,因此除了缺乏安全性之外,检查文件扩展名不是一种选择。
使用头文件中的mime类型是一个选项,我有代码可以做到这一点。
$file_info = new finfo(FILEINFO_MIME); // object oriented approach!
$mime_type = $file_info->buffer(file_get_contents($file)); // e.g. gives "image/jpeg"
switch($mime_type) {
case "image/jpeg":
// your actions go here...
}
然而,欺骗哑剧类型显然不是太难。
一些帖子建议在文件开头嗅出魔术数字,但这些也可能是欺骗性的。
对于有限的图像情况,可以使用
$imginfo_array = getimagesize($tempFile);
据我所知,这不适用于pdf,docs等。
即使将这些方法结合在一起似乎也不是很强大。然而,许多站点通常允许您上传,固定或以其他方式获取远程文件,并以某种方式管理安全问题。
非常感谢有关最佳安全性和验证实践的建议 - 如curl与file_get_contents vs. wd - 以及其他库或其他技术,以便在传输到我的服务器之前获取文件大小和文件类型。
注意:我希望允许传输主流图像格式,如.jpg和.gif,以及上传pdf文件,doc和docx文件,xls文件和类似的常见格式。
提前感谢您的建议和建议。
但是,我试图找到验证文件内容的最佳方法,以避免传播恶意代码
File uploading是我想在PHP生态系统中消除的攻击面之一。无论您是使用cURL下载文件还是允许用户从Web表单提交文件,解决方案都不会有太大变化。
解决远程代码执行问题:将文件上传到Web根目录外的不可公开访问的文件夹,然后使用代理脚本(提示:readfile()
或file_get_contents()
)提供,而不是允许直接访问。
然后,即使存在恶意代码,Apache / nginx也不会想到执行它。
...或者使用过大的文件加载我的服务器
如果你正在使用cURL,this is easily done。