用户将图像上传到服务器后,我们是否应该清理$_FILES['filename']['name']
?
我检查文件大小/文件类型等。但我不检查其他事情。是否存在潜在的安全漏洞?
谢谢
答案 0 :(得分:6)
绝对!正如@Bob已经提到的那样,覆盖普通文件名太容易了。
您可能还想要涵盖一些问题,例如,* nix中不允许Windows中允许的所有字符,反之亦然。文件名也可能包含相对路径,可能会覆盖其他未上载的文件。
以下是我为phunction PHP framework撰写的Upload()
方法:
function Upload($source, $destination, $chmod = null)
{
$result = array();
$destination = self::Path($destination);
if ((is_dir($destination) === true) && (array_key_exists($source, $_FILES) === true))
{
if (count($_FILES[$source], COUNT_RECURSIVE) == 5)
{
foreach ($_FILES[$source] as $key => $value)
{
$_FILES[$source][$key] = array($value);
}
}
foreach (array_map('basename', $_FILES[$source]['name']) as $key => $value)
{
$result[$value] = false;
if ($_FILES[$source]['error'][$key] == UPLOAD_ERR_OK)
{
$file = ph()->Text->Slug($value, '_', '.');
if (file_exists($destination . $file) === true)
{
$file = substr_replace($file, '_' . md5_file($_FILES[$source]['tmp_name'][$key]), strrpos($value, '.'), 0);
}
if (move_uploaded_file($_FILES[$source]['tmp_name'][$key], $destination . $file) === true)
{
if (self::Chmod($destination . $file, $chmod) === true)
{
$result[$value] = $destination . $file;
}
}
}
}
}
return $result;
}
重要的部分是:
array_map('basename', ...)
,这可以确保该文件不包含任何相对路径。ph()->Text->Slug()
,这可确保文件名中只允许.0-9a-zA-Z
,所有其他字符都替换为下划线(_
)md5_file()
,这已添加到文件名 iff 另一个同名文件已存在我更喜欢使用用户提供的名称,因为搜索引擎可以使用它来提供更好的结果,但如果这对您来说并不重要,那么简单的microtime(true)
或md5_file()
可以简化一些事情。< / p>
希望这有帮助! =)
答案 1 :(得分:4)
文件名是任意用户提供的字符串。作为一般规则,永远不要相信任意用户提供的值。
您永远不应该使用用户提供的文件名作为名称来保存服务器上的文件,始终创建自己的文件名。您可能想要做的唯一事情就是将其保存为元数据以供参考。输出元数据时,请采取通常的预防措施,如卫生和逃避。
答案 2 :(得分:1)
您还需要检查重复的名称。对于多个人来说,上传名为“mycat.jpg”的图片太容易了,如果上传到同一个文件夹会覆盖以前上传的同名文件。您可以通过在文件名中添加唯一ID来实现此目的(如Prix建议的那样)。还要验证文件类型不仅以图像扩展名结尾,而且还是实际图像;您不希望您的服务器充当随机文件的盲主机。