Php 保存上传的文件安全吗?

Php 保存上传的文件安全吗?,php,file,validation,upload,code-injection,Php,File,Validation,Upload,Code Injection,我正在尝试使用PHP构建一个简单的图像上传程序。我确实知道如何编写代码,但是我有一些顾虑 我的问题是:将用户发送的文件保存为原始文件是否安全?我的意思是:当我保存一个用户发送的文件时,我不会得到任何漏洞吗 假设我的PHP脚本是这样做的:它检索POST数据,其中包括我网站上一个人发送的文件。只需将文件移到一个包含原始名称、内容等的目录中就可以保存吗?这样做有什么害处吗?或者我应该将这些文件重命名为随机字符串吗 如果这不是一种安全的方法,那是什么?如何验证发送内容是否有害?确保只处理结尾正确的文件。

我正在尝试使用PHP构建一个简单的图像上传程序。我确实知道如何编写代码,但是我有一些顾虑

我的问题是:将用户发送的文件保存为原始文件是否安全?我的意思是:当我保存一个用户发送的文件时,我不会得到任何漏洞吗

假设我的PHP脚本是这样做的:它检索POST数据,其中包括我网站上一个人发送的文件。只需将文件移到一个包含原始名称、内容等的目录中就可以保存吗?这样做有什么害处吗?或者我应该将这些文件重命名为随机字符串吗


如果这不是一种安全的方法,那是什么?如何验证发送内容是否有害?

确保只处理结尾正确的文件。图像文件永远不会由Web服务器执行,但.php文件就是一个例子。因此,请确保用户不上传任何可以执行的文件


我不知道文件名是有害的。就内容而言,这很难回答。我记得在Windows上修改了TIFF图像的攻击向量,在LIJPEG上有一个*NIX系统的攻击向量。但是,如果不完全解码图像,您可能无法找到这些东西

存储和提供客户端提供的内容时总是存在漏洞

这篇博文很好地描述了您可能面临的漏洞、如何利用这些漏洞以及如何防范这些漏洞。我建议您将此作为参考:

JPEG文件除了包含实际图像数据外,还可以包含任意数据;这是规范的一部分。因此,仅仅检查图像是否是有效的JPEG并不意味着该文件一定是完全无害的

未经验证的文件上载 定义一个.htaccess文件,该文件只允许访问具有 允许的扩展。 不要将.htaccess文件放在 上传的文件将被存储。它应该放在父级中 目录 典型的.htaccess,仅允许gif、jpg、jpeg和png文件 应包括以下内容,以适应您自己的需要。这将 还可以防止双重扩展攻击

全盘否定 命令拒绝,允许 通融

如果可能,将文件上载到服务器根目录之外的目录中。 防止覆盖现有文件以阻止.htaccess 覆盖攻击

从这些mime类型创建接受的mime类型映射扩展的列表。 生成随机文件名并添加先前生成的扩展名。
不要只依赖客户端验证,因为这是不够的。理想情况下,应该同时实现服务器端和客户端验证。

这里有另一种方法:使用Paul Rouget基于Imgur.com的API编写的非常简短的图像上传程序

不要直接上传到你的数据库,让imgur做所有的安全和验证,然后如果需要,通过imgur链接或下载安全映像

它是免费的非商业和非常便宜的商业

基本上,您可以使用imgur的API从HTML页面安全地上传图像,而无需任何服务器端代码


这里有一个现场演示:

Pooh…有什么重要的理由让你自己去看吗?您只需使用imagemagick中的库即可。@bub改进我的编码,了解更多。。如果我仍然不知道问题的答案,那么使用库有什么意义呢?你最好使用白名单而不是黑名单。
HTML Form:
<form enctype="multipart/form-data" action="uploader.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload File" /> </form>
PHP Code:
<?php
$target_path  =  "uploads/";
$target_path  =  $target_path  .  basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";
} else {
echo "There was an error uploading the file, please try again!";
}
?>