1

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

表格代码

<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 文件 谁将文件上传到我的网站给我发了消息说“你只检查类型!” 并说“我使用了可以伪造输入字段并传递 PHP 文件的 firefox 扩展程序”。

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

4

2 回答 2

3

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

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

你应该使用

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

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

尝试破解这个,我使用PHP.net 手册中提到的 *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 并且没有人破解它以来,我正在使用此代码。

于 2013-02-02T09:52:28.570 回答
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避免路径遍历攻击的调用。

于 2013-02-02T09:56:14.420 回答