所以我有一个客户想要一个摄影网站,用户可以上传他们的照片以响应摄影比赛。虽然从技术上讲这不是问题,但我想知道与允许任何用户能够将任何图像上传到我的服务器相关的风险。感觉风险很大。。。
我正在考虑使用类似http://www.w3schools.com/php/php_file_upload.asp
如果我确实让匿名用户上传文件,我如何保护图像(以及可能具有破坏性的文件)将上传到的目录?
所以我有一个客户想要一个摄影网站,用户可以上传他们的照片以响应摄影比赛。虽然从技术上讲这不是问题,但我想知道与允许任何用户能够将任何图像上传到我的服务器相关的风险。感觉风险很大。。。
我正在考虑使用类似http://www.w3schools.com/php/php_file_upload.asp
如果我确实让匿名用户上传文件,我如何保护图像(以及可能具有破坏性的文件)将上传到的目录?
如果您想确保图像是真实图像,您可以使用 gd http://www.php.net/gd加载
如果 gd 资源创建正确,则图像是真实图像
首先使用以下方法检测 mime:
getimagesize($filename);
然后,例如,如果它是将 jpeg 加载到 gd 中:
$gdresource = imagecreatefromjpeg($filename);
如果$gdresource
有效/创建时没有警告,则图像有效且未损坏... getimagesize()
(可能)不足以检测损坏的图像
另外,另一个重要注意事项...不要依赖,$_FILES['blabla']['name']
因为它可能包含无效的 utf-8 序列(例如,假设您使用的是 utf-8)并且它可能是潜在的攻击机制,因为任何用户输入
所以你还需要验证/清理它
$originalFileName = $_FILES['blabla']['name'];
$safeOriginalFileName = iconv('UTF-8', 'UTF-8//IGNORE', $originalFileName);
// more additional checks here. for example filename is empty ""
move_uploaded_file(...., $safeOriginalFileName);
另外,请记住$_FILES['blabla']['name']
包含文件扩展名,这可能不正确。因此您需要将其剥离并使用实际正确的扩展名(您之前使用 解决getimagesize() + imagecreatefrom*()
)
$safeOriginalFileName = basename( $safeOriginalFileName ); // removes the extension
$safeOriginalFileName = $safeOriginalFileName . ".jpg"; // correct extension
希望这可以帮助 :)
也正如 DaveRandom 指出的那样,不要依赖$_FILES['blabla']['type']
,而是按照我的建议使用getimagesize() + imagecreatefrom*()
您将不得不进行一些研究,但主要是以下主要提示:
您可以拥有的基本安全措施是实际检查图像的 MIME 类型和扩展名。虽然这当然很容易伪造。
readfile()
使用像,fopen()
和之类的二进制安全函数file_get_contents()
,我不记得究竟是哪些,但是有一些 php 函数在处理文件时存在安全问题,研究哪些是并避免它们。
有一些使用preg_match()
和类似的功能将检查您正在阅读的文件中是否有类似于脚本的内容。使用它们来确保没有隐藏的脚本。这会稍微减慢这个过程,因为preg_match()
读取大文件可能会耗费资源,但它不应该很明显
您还可以像电子邮件服务一样触发防病毒软件在上传的文件上运行。
据我所知,具有潜在破坏性的图像通常会包含脚本语言,例如用于尝试 XSS 攻击的 php 代码或 javascript,存在很多危险,所以我猜你不能保证文件 100% 安全,但请定期查看所有新的危险和避免它们的方法。
上传的文件存储在一个临时位置,这个位置可以在$_FILES
变量中找到。
当您的脚本接受上传的文件时,您可以使用move_uploaded_file()
将其移动到您选择的位置。
因此,即使用户是匿名的,您也可以控制如何处理上传以及是否接受它们(例如,基于内容、大小等)。
此外,(匿名)用户提供文件和附带的详细信息。因此,如果您盲目地使用这些详细信息,那么您很容易受到攻击(有不良意图的用户可能会提供错误的详细信息,以使其合法化)。因此,如果您需要这些详细信息,请自己收集它们(而不是使用$_FILES
)!
有关更多信息,请参阅PHP 文档