【问题标题】:validating file upload server side - allow only images with php验证文件上传服务器端 - 只允许带有 php 的图像
【发布时间】:2012-04-24 15:34:27
【问题描述】:

这里的新人提出了一个问题,即应该用简单的解决方案来解决什么问题。

我已经尝试了一堆代码。看来我可以获取 getimagesize 的文件流并让其他事情正常工作而不会崩溃。

我正在清理一个旧项目,该项目需要限制上传的文件,以便它们只是图像文件而不是邪恶的。

无论如何,这段代码总是给我一个错误信息

$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']);  
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') {  
alert ("Sorry, we only accept GIF and JPEG images");  
exit;  
}  

这是黑名单工作

$blacklist = array(".php", ".phtml", ".php3", ".php4", ".js", ".shtml", ".pl" ,".py"   
,".txt", ".doc");

foreach ($blacklist as $file)
{
if(preg_match("/$file\$/i", $_FILES['bf_file'][$key]['tmp_name']))
{
alert "ERROR: Uploading executable files Not Allowed\n";
exit();
}
} 

这是另一个getimagesize

$size = getimagesize($_FILES[bf_file][$key][tmp_name]);
$fp = fopen($_FILES[bf_file][$key][tmp_name], "rb");
if ($size && $fp) {
header("Content-type: {$size['mime']}");
fpassthru($fp);
continue;
} else
// error
alert("Inappropriate file type"); 

无论文件是否上传,我都会收到错误消息。

我只需要将这些控件放在我的文件中的某个位置,这样如果上传的文件通过了检查,那么所有内容都只是作为上传者通过,其他所有内容都可以正常工作,但没有这些限制器和检查的好处。

此外,不应要求用户上传文件。有3个字段,主题,正文和文件上传。只有主体和主体需要拥有数据,并且现在有效。

任何帮助将不胜感激。

谢谢,

詹姆斯

【问题讨论】:

  • $key 的值是多少?不管它包含什么,由于很久以前某些 PHP 作者的一些 premium 愚蠢,您需要引用 $_FILES['bf_file']['tmp_name'][$key] 而不是 $_FILES['bf_file'][$key]['tmp_name']。另请注意,getimagesize() 是唯一明智的做法,我什至无法在评论给我的少量空间中开始解释您的黑名单方法有什么问题。
  • 这是一个:您的 preg_match 不是多行的,因此容易受到空格攻击。使用白名单而不是黑名单的一千个理由之一。此外,您确实需要从图像画布中复制像素数据,如果您只是按原样保存文件,那么您很容易受到恶意用户上传包含嵌入式服务器端脚本的图像文件的攻击。
  • @Cheekysoft,还有index.php5(可能存在)和index.php.frcontent negotiation

标签: php security validation image-uploading


【解决方案1】:

在第一个 sn-p 中。好吧,getimagesize() 实际上返回 MIME 类型(与 Baba 所说的相反),但您不应该依赖它。完全有可能制作一开始看起来像 PNG GIF 的文件(有什么理由阻止 PNG?),但在标题之后有 <?php dangerous_code(); ?>。另外,我不知道你在用[$key] 做什么。我不知道它是做什么的,数组看起来像$_FILES[$form_name][$file_field](例如$_FILES['file_input']['tmp_size']。没有第三个字段。除非您正在上传多个文件,否则请查看Baba所说的(这是非常hacky的功能)。下一个, PHP 没有 alert() - 你的意思可能是 echo

在第二个 sn-p 中,我发现你做错了。点是正则表达式中的元字符,但在这种情况下它并不重要。无论如何,黑名单方法都有缺陷,因为您不知道您的服务器是否不支持 .php5 扩展名。即使没有,也有人可以通过制作文件hack.php.fr 在Apache 中滥用content negotiation(Apache 认为.fr 是语言)。您的方法有缺陷 - 无论原始扩展名是什么,只要给 PNG 文件 .png 扩展名等等。

在第三个示例中,您激活了错误的变量 - 但也使用了裸字(您不应该,虽然我知道您应该使用大写常量(因此与 PHP 所说的相反,如果您有裸字并没有那么危险)常识),它们非常慢,比普通字符串慢得多,如果你有E_NOTICE(提示:你应该)会犯很多错误。接下来,continue 不适用于 if 条件 - 它适用于循环条件(它也适用于 switch(如 break),但我想这只是为了保持一致性)。

至于不必上传文件,这很容易。只需对isset($_FILES['file_input_name']) 进行条件处理即可。

tl;dr - 正确学习 PHP

【讨论】:

  • so contrary to what PHP says, barewords aren't so dangerous if you have common sense - 公平点,但它们仍然使您的错误日志混乱,容易避免错误。
【解决方案2】:

你的脚本到处都是例子

$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']);

获取临时名称应该是$_FILES['bf_file']['tmp_name'][$key],并且文件大小已经通过$_FILES['bf_file']['size'][$key]返回

你为什么不看看类似问题的详细示例

multi image upload wrong quantity on file-upload

Uploading images with the help of arrays and fetch errors

【讨论】:

  • 很明显,我只是环顾四周,从网上抓取这些代码并将它们扔到我的页面中。说到$key的位置,出现这个是因为可以上传多张图片吗?谢谢
  • 不客气..点击链接有详细的例子之前做过......而且它的字符串非常前卫..你不应该有自定义它的问题
【解决方案3】:

到目前为止,最安全的方法是阻止您的网络服务器在用户可以完全上传到的文件夹中执行动态内容。那么他们上传什么都没有关系。

上传目录中包含php_flag engine off 的.htaccess 文件将阻止php。无论如何,其他可执行的东西应该默认被禁用,但你一定要检查一下。

【讨论】:

    猜你喜欢
    • 2014-11-09
    • 2011-03-13
    • 2019-06-11
    • 1970-01-01
    • 2021-09-01
    • 2013-10-28
    • 1970-01-01
    • 2018-06-15
    • 2013-01-29
    相关资源
    最近更新 更多