0

我已经玩了很久了,似乎无法弄清楚它为什么会发生 - 我正在关注“PhpAcademy”教程并拥有以下代码(我只是使用 phpmyadmin 上传用户配置文件图片基于session):问题是当我选择文件并单击“上传”时,图像文件没有显示在 phpmyadmin 中的“imagelocation”下。任何帮助将不胜感激。谢谢!

应该启动上传过程的“UPLOADPROFILEPIC.PHP”文件:

<?php

$_SESSION['username']="atestuser508";

$username = $_SESSION['username'];

echo "Welcome, ".$username."!<br/>";

if ($_POST['submit']) {
// get file attributes
$name = $_FILES['myfile']['name'];
$tmp_name = $_FILES['myfile']['tmp_name'];

if ($name)
{
    // start the upload process

    $location = "avatars/$name";
    move_uploaded_file($tmp_name,$location);

    $query = mysql_query("UPDATE members SET imagelocation='$location' WHERE username='$username'");

    die("You've successfully uploaded your profile pic! <a href='login-home.php'>Return to your profile</a>");
}
else
die("Please select a file to upload!");
}

echo "Upload a profile picture:

<form action='uploadprofilepic.php' method='POST' enctype='multipart/form-data'>
File: <input type='file' name='myfile'><input type='submit' name='submit' value='Upload!'>
</form>

";  
?>

应该允许用户上传并显示个人资料图片的“个人资料”页面:

<?php include("uploadprofilepic.php"); ?>
<?php
$query = mysql_query("SELECT * FROM members WHERE username='$username'");
if (mysql_num_rows($query)==0) 
die("User not found!");
else {
$row = mysql_fetch_assoc($query);
$location = $row['imagelocation'];

echo "<img src='$location'>";
}

?>

4

1 回答 1

1

您的代码将允许恶意用户在您的服务器上的任何位置上传他们想要的任何文件。您盲目地相信该['name']参数是“安全的”。您的代码中没有任何错误处理,并假设一切都会好起来的。

换句话说,你刚刚在你的服务器上打开了一个巨大的安全漏洞,任何有一点兴趣的人都可以驾驶海盗船通过。

在绝对 BARE 最低限度,您需要以这种方式检查上传是否成功:

if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
    ... file was uploaded ok
} else {
    die("Upload failed with error code " . $_FILES['file']['error']);
}

永远不要相信用户提供的任何东西。在文件上传时,即 a) 文件名 ( ['name']),b) 文件的 mime 类型 ( ['type'])。两者都是微不足道的操纵。

确认上传成功后,您需要检查他们是否确实上传了图像,而不是“maliciousscript-that-gives-them-total-control.php”或“nasty_virus.exe”:

$info = getimagesize($_FILEs['file']['tmp_name']);
if ($info === FALSE) {
    die("You didn't upload a valid image type");
}

然后,对于在您的服务器上存储此上传文件的文件名,永远不要使用用户提供的名称。自己生成一个。由于您将有关此图像的详细信息存储在“成员”表中,因此请使用该用户的成员 ID(您确实在该表上有一个主键,对吗?)。所以代替/site/images/userprovidedfilename.jpg, make 它/site/images/37(假设用户的 id 为 37)。

确保文件移动确实成功:

$status = move_uploaded_file($_FILEs['file']['tmp_name'], '/some/path/that/you/generated');
if ($status === FALSE) {
    die("Unable to move uploaded file to destination");
}

然后更新数据库,检查以确保查询实际成功:

$sql = "...";
$result = mysql_query($sql);
if ($result === FALSE) {
   die(mysql_error());
}

这是您在保护上传脚本时应该做的最低限度的工作。还有更多可以做的事情,但这应该可以保护您免受除最坚定的攻击者之外的所有人的伤害。即使您没有受到攻击,错误处理也将有助于抓住事情因正当理由而爆发的时间。

于 2011-10-06T04:13:29.260 回答