PHP中的文件上载问题

PHP中的文件上载问题,php,file-upload,Php,File Upload,嗨,我正在尝试使用php脚本上传一个图像。真正奇怪的是,只有在Internet Explorer everywhere中,我才发现以下错误:脚本工作正常: Warning: move_uploaded_file(pictures/) [function.move-uploaded-file]: failed to open stream: Is a directory in /home/tntauto1/public_html/admin_add1.php on line 59 Warning

嗨,我正在尝试使用php脚本上传一个图像。真正奇怪的是,只有在Internet Explorer everywhere中,我才发现以下错误:脚本工作正常:

Warning: move_uploaded_file(pictures/) [function.move-uploaded-file]: failed to open stream: Is a directory in /home/tntauto1/public_html/admin_add1.php on line 59

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpcJnHZE' to 'pictures/' in /home/tntauto1/public_html/admin_add1.php on line 59

Warning: copy() [function.copy]: The first argument to copy() function cannot be a directory in /home/tntauto1/public_html/admin_add1.php on line 60
以下是脚本:

if(is_uploaded_file($_FILES['image']['tmp_name'])){
    if($_FILES['image']['type'] == 'image/jpeg'){
        $original = 'original_'.$v_id.'.jpg';
        $large = 'large_'.$v_id.'.jpg';
        $small = 'small_'.$v_id.'.jpg';

    }elseif($_FILES['image']['type'] == 'image/gif'){
        $original = 'original_'.$v_id.'.gif';
        $large = 'large_'.$v_id.'.gif';
        $small = 'small_'.$v_id.'.gif';
    }else{
        $error = 'Error: The image could not be uploaded. It must be in .jpg, .jpeg or .gif format.';
    }
    if(move_uploaded_file($_FILES['image']['tmp_name'],'pictures/'.$large)){}
        copy('pictures/'.$large,'pictures/'.$small);

    $imgsize = getimagesize('pictures/'.$large); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>---- Resize to 480 X 360
    $width = $imgsize[0];
    $height = $imgsize[1];
    if(($width > 480) || ($height > 360)){//resize the image
        $ratio = $width / $height;
        if(100 / $ratio >= 80){//calculates if height of uploaded image is too large
            $new_width = floor(360 * $ratio);
            $new_height = 360;
        }elseif(150 * $ratio > 100){// calculate if width of uploaded image is too large
            $new_width = 480;
            $new_height = floor(480 / $ratio);
        }
        if($_FILES['image']['type'] == 'image/jpeg'){
            $img = imagecreatefromjpeg('pictures/'.$large);
            $img_copy = imagecreatetruecolor($new_width,$new_height);
            imagecopyresampled($img_copy,$img,0,0,0,0,$new_width,$new_height,$width,$height);
            imagejpeg($img_copy,'pictures/'.$large,100);    
        }
        if($_FILES['image']['type'] == 'image/gif'){
            $img = imagecreatefromjpeg('pictures/'.$large);
            $img_copy = imagecreatetruecolor($new_width,$new_height);
            imagecopyresampled($img_copy,$img,0,0,0,0,$new_width,$new_height,$width,$height);
            imagejpeg($img_copy,'pictures/'.$large,100);    
        }
    }   

无法移动目录,因为$large没有值或已重置。

无法移动目录,因为$large没有值或已重置

if($FILES['image']['type'] == 'image/jpeg'){
保存文件上载数据的变量应为$\u FILES。由于$FILES是一个刚刚使用过的空变量,所以$large变量也是空的,所以您要将一个文件移动到pictures/目录,就像PHP告诉您的那样。$error还应该包含错误消息,因为在它为true之前没有任何ifs

避免此类错误的一种方法是将error_reporting设置为E_,所有这些都会显示$FILES变量a typo未定义的通知

if($_FILES['image']['type'] == 'image/jpeg'){
保存文件上载数据的变量应为$\u FILES。由于$FILES是一个刚刚使用过的空变量,所以$large变量也是空的,所以您要将一个文件移动到pictures/目录,就像PHP告诉您的那样。$error还应该包含错误消息,因为在它为true之前没有任何ifs

避免此类错误的一种方法是将error_reporting设置为E_,所有这些都会显示$FILES变量a typo未定义的通知

if($_FILES['image']['type'] == 'image/jpeg'){
切勿依赖浏览器提交的MIME类型

在这种情况下,您的问题正如david提到的:IE通常错误地为JPEG提供image/pjpeg,因此您检测到未知的文件类型,并将$error设置为error:无法上载图像。它必须是.jpg、.jpeg或.gif格式。。。。但是,尽管如此,您仍然尝试移动文件,尽管没有设置$small或$large

但除此之外,浏览器提交的类型可能是完全错误的。你不能相信上传的文件名或媒体类型是合适的,所以甚至不用检查它们。相反,在调用getimagesize后查看$imgsize[2],以了解PHP认为图像是什么类型

而且。。。如果您接受来自普通用户的图像上载,则会出现安全问题。完全可以创建包含HTML标记的有效GIF或其他文件类型。然后,当愚蠢的IE以页面的形式单独访问GIF时,它将检测HTML标记,确定您告诉它的内容类型一定是错误的,并将其解释为HTML页面,包括其中的任何JavaScript,然后在您的站点安全上下文中执行

如果您必须允许从不受信任的源上载文件,并且您自己不处理图像,这通常会产生删除不需要的HTML的副作用,那么您通常必须从不同的主机名为图像提供服务,以避免将图像脚本化到您的站点中

切勿依赖浏览器提交的MIME类型

在这种情况下,您的问题正如david提到的:IE通常错误地为JPEG提供image/pjpeg,因此您检测到未知的文件类型,并将$error设置为error:无法上载图像。它必须是.jpg、.jpeg或.gif格式。。。。但是,尽管如此,您仍然尝试移动文件,尽管没有设置$small或$large

但除此之外,浏览器提交的类型可能是完全错误的。你不能相信上传的文件名或媒体类型是合适的,所以甚至不用检查它们。相反,在调用getimagesize后查看$imgsize[2],以了解PHP认为图像是什么类型

而且。。。如果您接受来自普通用户的图像上载,则会出现安全问题。完全可以创建包含HTML标记的有效GIF或其他文件类型。然后,当愚蠢的IE以页面的形式单独访问GIF时,它将检测HTML标记,确定您告诉它的内容类型一定是错误的,并将其解释为HTML页面,包括其中的任何JavaScript,然后在您的站点安全上下文中执行


如果您必须允许从不受信任的来源上载文件,并且您自己不处理图像,这通常会产生删除不需要的HTML的副作用,那么您通常必须从不同的主机名提供图像,以避免它们被脚本写入您的站点。

忽略此答案,看起来好像你只是因为问题的格式错误才打错了字。我同意david.scheider的答案,在从IE上传时检查返回的mime类型。忽略这个答案,看起来似乎只是因为问题的格式错误而导致输入错误。我同意david.scheider的回答,从IE上传时检查返回的mime类型。嘿,谢谢大家的输入。不按文件类型检查它$\u FILES['name']['type']修复了它。很抱歉,我没有提到$large变量是在我之前没有发布的脚本中定义的。谢谢大家的支持
放不按文件类型检查它$\u FILES['name']['type']修复了它。抱歉,我没有提到$large变量是在脚本的前面定义的,我不知道您可以在图像中嵌入HTML。怎么会这样呢?更重要的是,如何检测上载的图像包含HTML标记并进行相应处理?下面是一个有趣的示例:。试图检测任意文件中的标记是一种注定要失败的方法,因为您必须使用与浏览器相同的启发式方法,浏览器是可变的且没有文档记录的。相反,如上所述,从不同的主机名提供您的用户内容,这样,如果它得到XSS,就不会控制您的主站点。非常有趣。我可以在检查图像文件时看到HTML标记。有些人建议从上传的图像中创建一个新图像,以删除文件和/或元数据中可能存在的HTML和脚本。这样行吗?我正在考虑就我的特殊情况发布一个关于此的问题。当然,重新压缩图像会给您删除元数据的机会。这仍然存在攻击者发送图像数据的可能性,这些图像数据在压缩时会产生类似HTML标记的数据。假设攻击者可以访问相同的压缩器代码进行分析和攻击,这是一种有趣但肯定很困难的攻击;对于JPEG可能不可行,但对于某些无损格式可能更可行。关于这一点,我已经问了一个问题。如果你愿意,你可以查看并回答。我不知道你可以在图像中嵌入HTML。怎么会这样呢?更重要的是,如何检测上载的图像包含HTML标记并进行相应处理?下面是一个有趣的示例:。试图检测任意文件中的标记是一种注定要失败的方法,因为您必须使用与浏览器相同的启发式方法,浏览器是可变的且没有文档记录的。相反,如上所述,从不同的主机名提供您的用户内容,这样,如果它得到XSS,就不会控制您的主站点。非常有趣。我可以在检查图像文件时看到HTML标记。有些人建议从上传的图像中创建一个新图像,以删除文件和/或元数据中可能存在的HTML和脚本。这样行吗?我正在考虑就我的特殊情况发布一个关于此的问题。当然,重新压缩图像会给您删除元数据的机会。这仍然存在攻击者发送图像数据的可能性,这些图像数据在压缩时会产生类似HTML标记的数据。假设攻击者可以访问相同的压缩器代码进行分析和攻击,这是一种有趣但肯定很困难的攻击;对于JPEG可能不可行,但对于某些无损格式可能更可行。关于这一点,我已经问了一个问题。如果你愿意,你可以查看并回答。