绕过表单输入字段以上载不需要的文件

时间:2013-02-02 09:48:15

标签: php security

我的网站上传了会员资料图片部分,我使用了以下代码。

表单代码

<form action="send.php" method="post" enctype="multipart/form-data" name="send" id="send">
    Your Image : <input type="file" name="pic" id="pic"/>
    <input type="Submit" name="Submit" value="Submit"/>
</form>

PHP代码send.php

$ImageName = $_FILES[pic][name]; 
if(!empty($ImageName) && $_FILES[pic][type] == "image/jpeg" || $_FILES[pic][type] == "image/png" || $_FILES[pic][type] == "image/gif" || $_FILES[pic][type] == "image/bmp"){
    $t = time();
    $NewImageName = "$t$ImageName"; // image new name
    copy($_FILES[pic][tmp_name], "users/$NewImageName"); // copy it to directory
} else {
    echo "no upload done";
}

但有人使用firefox扩展程序设法绕过它并上传php文件 谁将文件上传到我的网站发给我的消息说“你只检查类型!” 并说“我使用firefox扩展,可以伪造输入字段并传递PHP文件”。

所以我的问题 如何保护上面代码的图片上传形式? 〜谢谢

2 个答案:

答案 0 :(得分:3)

首先,我认为这不是读取$ _FILE变量的有效格式

$ImageName = $_FILES[pic][name]; 

你应该使用

$ImageName = $_FILES['pic'][name];

然后我认为有人可能伪造服务器端检查是不可能的。

试着破解这个,我使用PHP.net Manual中提到的* PATHINFO_EXTENSION *

$validFormat = array("jpg","JPG","jpeg","JPEG","png","PNG","gif","GIF");    
$path = pathinfo($_FILES['pic']['name'], PATHINFO_EXTENSION);
if(in_array($path, $validFormat)){
// it's okay
}else{
// Error
}

我正在使用这段代码,因为我刚刚发现了pathinfo而且没有人破解它..

答案 1 :(得分:3)

"type"数组中的$_FILES条目确实只是客户端发送的值。不要相信他们。

文件作为php执行,不是基于客户端给出的MIME类型(或从其数据中识别的MIME类型),而是基于它们的扩展名。

$imageName = $_FILES['pic']['name'];

if (isset($imageName)) {
    $ext = pathinfo($imageName, PATHINFO_EXTENSION);
    if (in_array(strtolower($ext), array('jpg', 'jpeg', 'gif', 'png', 'bmp')) {
        $t = time();
        $newImageName = $t . basename($imageName);
        copy($_FILES['pic']['tmp_name'], 'users/' . $newImageName);
    }
} else {
    echo 'no upload done';
}

请注意调用pathinfo以获取扩展名,并basename以避免path traversal attacks