如何保护此图片上传代码
how to secure this image upload code
我在过去两周内遭到黑客攻击,我在日志文件中看到黑客可以在注册时上传 php 个 shell
这是让用户注册并将数据保存到站点数据库的表单,重点是当他上传他的头像时,他可以上传 php 文件
<form method="post" name="regiterationForm" id="regiterationForm" enctype="multipart/form-data">
<table width="930" border="0" align="center" cellpadding="2" cellspacing="2">
<tr>
<td width="431" valign="top"><table width="500" border="0" cellspacing="2" cellpadding="2">
<tr>
<td width="215" align="right" class="registerpage_form_credential">Username:</td>
<td colspan="3" class="registersignupbox_bg">
<input onBlur="checkUserName(this.value);" type="text" name="userName" id="userName" class="register_signup_field" /> </td>
<div class="errormsg" id="error_userName" style="display:none;"><span class="noberr"></span><span id="error_userName_val">Please enter name</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Password:</td>
<td colspan="3" class="registersignupbox_bg"><input type="password" name="userPassword" id="userPassword" class="register_signup_field" /> </td>
<div class="errormsg errpass" id="error_userPassword" style="display:none;"><span class="noberr"></span><span id="error_userPassword_val">Please enter password</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Retype Password:</td>
<td colspan="3" class="registersignupbox_bg"><input type="password" name="userRetypePassword" id="userRetypePassword" class="register_signup_field" /> </td>
<div class="errormsg errpass1" id="error_userRetypePassword" style="display:none;"><span class="noberr"></span><span id="error_userRetypePassword_val">Please enter password</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Your real name:</td>
<td colspan="3" class="registersignupbox_bg"><input type="text" name="userRealName" id="userRealName" class="register_signup_field" /> </td>
<div class="errormsg errpass2" id="error_userRealName" style="display:none;"><span class="noberr"></span><span id="error_userRealName_val">Please enter Name</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">E-mail address:</td>
<td colspan="3" class="registersignupbox_bg"><input onBlur="checkUserEmail(this.value);" type="text" name="userEmail" id="userEmail" class="register_signup_field" />
</td>
<div class="errormsg errpass3" id="error_userEmail" style="display:none;"><span class="noberr"></span><span id="error_userEmail_val">Please enter Email</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Retype E-mail address:</td>
<td colspan="3" class="registersignupbox_bg"><input type="text" name="userRetypeEmail" id="userRetypeEmail" class="register_signup_field" />
</td>
<div class="errormsg errpass4" id="error_userRetypeEmail" style="display:none;"><span class="noberr"></span><span id="error_userRetypeEmail_val">Please enter Email</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Country:</td>
<td colspan="3" class="registersignupbox_bg"><select name="country" id="country" class="register_monthday_selection">
<option value="">Choose a Country</option>
<?php for($i=0; $i<count($allCountryName); $i++){ ?>
<option value="<?php echo $allCountryName[$i]['name']; ?>"><?php echo $allCountryName[$i]['name']; ?></option>
<?php } ?>
</select>
</td>
<div class="errormsg errpass5" id="error_country" style="display:none;"><span class="noberr"></span><span id="error_country_val">Please Select Country</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Date of birth:</td>
<td class="register_day_bg"><select name="userDay" id="userDay" class="register_day_selection">
<option value="">Day</option>
<?php for($i=1; $i<=31; $i++){ ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php } ?>
</select></td>
<td class="register_month_bg"><select name="userMonth" id="userMonth" class="register_month_selection">
<option value="">Month</option>
<?php $month_digit_array = array("1"=>"January","2"=>"February","3"=>"March","4"=>"April","5"=>"May","6"=>"June","7"=>"July","8"=>"August","9"=>"September","10"=>"October","11"=>"November","12"=>"December");
for($i=1; $i<=12; $i++){
?>
<option value="<?php echo $i; ?>"><?php echo $month_digit_array[$i]; ?></option>
<?php } ?>
</select></td>
<td class="register_year_bg"><select name="userYear" id="userYear" class="register_year_selection">
<option value="">Year</option>
<?php $curYear = date('Y'); for($i=$curYear; $i>=1930; $i--){ ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php } ?>
</select></td>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">I am a:</td>
<td colspan="3" class="registersignupbox_bg"><select name="gender" id="gender" class="register_monthday_selection">
<option value="">Select an option</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select></td>
<div class="errormsg errpass6" id="error_gender" style="display:none;"><span class="noberr"></span><span id="error_gender_val">Please Select Gender</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Select an Avatar:</td>
<td colspan="3" class="registersignupbox_bg"><input type="file" id="image" name="userAvatar" /></td>
<div class="errormsg errpass7" id="error_image" style="display:none;"><span class="noberr"></span><span id="error_image_val">Please Select Image</div>
</tr>
<tr>
<td colspan="4" style="
padding-left: 37%;
"><div class="g-recaptcha" data-sitekey="6LfhvAkTAAAAAFQyqmN2nf9hXEY1T0jF89SCGNVB"></div>
</td>
</tr>
</table></td>
<td width="455">
<p>
<iframe width="555" height="312" src="https://www.youtube.com/embed/vkjFm6ClTuw" frameborder="0" allowfullscreen></iframe>
</p>
<br />
<div style="width:468px ;margin: 0 auto; height:60px">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Header/Footer Small -->
<ins class="adsbygoogle"
style="display:inline-block;width:468px;height:60px"
data-ad-client="ca-pub-5794587985510139"
data-ad-slot="5064971004"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</td>
</tr>
<tr>
<td colspan="2"><table width="709" border="0" align="center" cellpadding="2" cellspacing="2" style="margin-top:11px; margin-top: 15px !important;
margin-right: 67px;" class="signp">
<tr>
<td> </td>
<td class="contactus_form_credentials"> </td>
</tr>
<tr>
<td width="21" align="center"><label>
<input type="checkbox" name="promotion" id="promotion"/>
</label></td>
<td width="442" class="contactus_form_credentials">I agree that my account will be deleted if my email is not valid</td>
</tr>
<tr>
<td align="center"><input type="checkbox" name="checkbox2" id="checkbox2"/></td>
<td class="contactus_form_credentials">I have read and agree to the (example.com) <a href="terms.php" class="termsofuse">Terms of use</a></td>
</tr>
<tr>
<td> </td>
<td style="cursor:pointer;" onclick="registerFormValidation();"><img src="images/register_signup_btn.png" width="220" height="108" /></td>
</tr>
</table></td>
</tr>
</table>
<div class="errormsg errpass7" id="error_captcha" style="display:none;"><span class="noberr"></span><span id="error_captcha_val"></div>
</form>
这是注册函数
function insertData($arr,$files){
$username =$arr['userName'];
$pass =$arr['userPassword'];
$realname =$arr['userRealName'];
$email =$arr['userEmail'];
$country =$arr['country'];
$gender =$arr['gender'];
$dob =$arr['userDay'].'-'.$arr['userMonth'].'-'.$arr['userYear'];
if(self::userNameExit($username) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
if(self::userEmailExist($email) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
require_once(COMM_PATH."DatabaseManager.php");
$db= new DatabaseManager();
$emailcode = rand().time();
$sql = "Insert into users(username,pass,realname,email,country,dob,gender,lastlogin,register_date,email_varification,email_code)values('".$username."','".md5($pass)."','".$realname."','".$email."','".$country."','".$dob."','".$gender."', now(), now(),'n','".$emailcode."')";
$result = $db->executeUpdate($sql);
$user_id = $db->lastInsertId();
self::autoFriends($user_id);
self::sentMessage($user_id,$username);
insertStatusNow($user_id,"user");
if(isset($files['userAvatar']['name']) && $files['userAvatar']['name'] !=""){
$nameOfImage = time()."_".basename($files['userAvatar']['name']);
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
}
我想知道我怎么了,网站被黑了,生意每天都在下降
更新::
if(isset($files['userAvatar']['name']) && $files['userAvatar']['name'] !=""){
$nameOfImage = $files['userAvatar']['name'];
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(in_array($fileType = $fileInfo->file($nameOfImage, FILEINFO_MIME_TYPE, $allowedMIMETypes))){
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
else {
die("check you reg");
}
return null;
我已经制作了这样的代码,但它允许用户注册但没有照片
所以你想要的是人们只上传图片而不是 PHP 脚本。那么答案很简单,检查文件扩展名。但话虽这么说,还是有一些方法,比如注入 %00
(不确定操作码)来欺骗 PHP 服务器。最好获得一个现有的图书馆来为您检查。一旦完成,为了不执行上传的脚本,不要给它执行权限。这样即使攻击者上传 php 文件,它也不会被您的服务器处理。如果你正确检查扩展,当攻击者假设上传 c99 shell 时,只会在上传路径中看到损坏的图像,而不是实际的 shell 页面,因为它正在通过图像网络服务器
使用它来检查文件的 MIME 类型:
$file = $files['userAvatar']['name'];
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(in_array($fileType = $fileInfo->file($file, FILEINFO_MIME_TYPE, $allowedMIMETypes)){
//the file is an image
} else {
//file doesn't have a whitelisted MIME-type
}
更新:
如果你想阻止用户在没有头像的情况下注册,只需在将用户插入数据库之前输入我给你的代码即可。你的整个函数会变成这样:
function insertData($arr,$files){
$username =$arr['userName'];
$pass =$arr['userPassword'];
$realname =$arr['userRealName'];
$email =$arr['userEmail'];
$country =$arr['country'];
$gender =$arr['gender'];
$dob =$arr['userDay'].'-'.$arr['userMonth'].'-'.$arr['userYear'];
if(self::userNameExit($username) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
if(self::userEmailExist($email) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
//*************
if(!isset($files['userAvatar']['name']) || empty($files['userAvatar']['name'])){
//no file was uploaded, give some kind of error message
}
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(!in_array($fileType = $fileInfo->file($nameOfImage, FILEINFO_MIME_TYPE, $allowedMIMETypes))){
//the uploaded file wasn't recognized as an image, give some kind of error message
}
*************//
require_once(COMM_PATH."DatabaseManager.php");
$db= new DatabaseManager();
$emailcode = rand().time();
$sql = "Insert into users(username,pass,realname,email,country,dob,gender,lastlogin,register_date,email_varification,email_code)values('".$username."','".md5($pass)."','".$realname."','".$email."','".$country."','".$dob."','".$gender."', now(), now(),'n','".$emailcode."')";
$result = $db->executeUpdate($sql);
$user_id = $db->lastInsertId();
self::autoFriends($user_id);
self::sentMessage($user_id,$username);
insertStatusNow($user_id,"user");
$nameOfImage = time()."_".basename($files['userAvatar']['name']);
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
此外,我看到您通过使用 JavaScrip 将用户重定向到注册页面来处理错误(甚至没有使用 PHP
header()
函数)。这不是很优雅,用户不会知道他们做错了什么,所以我建议您 return 来自该函数的错误消息,然后在注册页面上回显
我在过去两周内遭到黑客攻击,我在日志文件中看到黑客可以在注册时上传 php 个 shell
这是让用户注册并将数据保存到站点数据库的表单,重点是当他上传他的头像时,他可以上传 php 文件
<form method="post" name="regiterationForm" id="regiterationForm" enctype="multipart/form-data">
<table width="930" border="0" align="center" cellpadding="2" cellspacing="2">
<tr>
<td width="431" valign="top"><table width="500" border="0" cellspacing="2" cellpadding="2">
<tr>
<td width="215" align="right" class="registerpage_form_credential">Username:</td>
<td colspan="3" class="registersignupbox_bg">
<input onBlur="checkUserName(this.value);" type="text" name="userName" id="userName" class="register_signup_field" /> </td>
<div class="errormsg" id="error_userName" style="display:none;"><span class="noberr"></span><span id="error_userName_val">Please enter name</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Password:</td>
<td colspan="3" class="registersignupbox_bg"><input type="password" name="userPassword" id="userPassword" class="register_signup_field" /> </td>
<div class="errormsg errpass" id="error_userPassword" style="display:none;"><span class="noberr"></span><span id="error_userPassword_val">Please enter password</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Retype Password:</td>
<td colspan="3" class="registersignupbox_bg"><input type="password" name="userRetypePassword" id="userRetypePassword" class="register_signup_field" /> </td>
<div class="errormsg errpass1" id="error_userRetypePassword" style="display:none;"><span class="noberr"></span><span id="error_userRetypePassword_val">Please enter password</div>
</tr>
<tr>
<td width="215" align="right" class="registerpage_form_credential">Your real name:</td>
<td colspan="3" class="registersignupbox_bg"><input type="text" name="userRealName" id="userRealName" class="register_signup_field" /> </td>
<div class="errormsg errpass2" id="error_userRealName" style="display:none;"><span class="noberr"></span><span id="error_userRealName_val">Please enter Name</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">E-mail address:</td>
<td colspan="3" class="registersignupbox_bg"><input onBlur="checkUserEmail(this.value);" type="text" name="userEmail" id="userEmail" class="register_signup_field" />
</td>
<div class="errormsg errpass3" id="error_userEmail" style="display:none;"><span class="noberr"></span><span id="error_userEmail_val">Please enter Email</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Retype E-mail address:</td>
<td colspan="3" class="registersignupbox_bg"><input type="text" name="userRetypeEmail" id="userRetypeEmail" class="register_signup_field" />
</td>
<div class="errormsg errpass4" id="error_userRetypeEmail" style="display:none;"><span class="noberr"></span><span id="error_userRetypeEmail_val">Please enter Email</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Country:</td>
<td colspan="3" class="registersignupbox_bg"><select name="country" id="country" class="register_monthday_selection">
<option value="">Choose a Country</option>
<?php for($i=0; $i<count($allCountryName); $i++){ ?>
<option value="<?php echo $allCountryName[$i]['name']; ?>"><?php echo $allCountryName[$i]['name']; ?></option>
<?php } ?>
</select>
</td>
<div class="errormsg errpass5" id="error_country" style="display:none;"><span class="noberr"></span><span id="error_country_val">Please Select Country</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Date of birth:</td>
<td class="register_day_bg"><select name="userDay" id="userDay" class="register_day_selection">
<option value="">Day</option>
<?php for($i=1; $i<=31; $i++){ ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php } ?>
</select></td>
<td class="register_month_bg"><select name="userMonth" id="userMonth" class="register_month_selection">
<option value="">Month</option>
<?php $month_digit_array = array("1"=>"January","2"=>"February","3"=>"March","4"=>"April","5"=>"May","6"=>"June","7"=>"July","8"=>"August","9"=>"September","10"=>"October","11"=>"November","12"=>"December");
for($i=1; $i<=12; $i++){
?>
<option value="<?php echo $i; ?>"><?php echo $month_digit_array[$i]; ?></option>
<?php } ?>
</select></td>
<td class="register_year_bg"><select name="userYear" id="userYear" class="register_year_selection">
<option value="">Year</option>
<?php $curYear = date('Y'); for($i=$curYear; $i>=1930; $i--){ ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php } ?>
</select></td>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">I am a:</td>
<td colspan="3" class="registersignupbox_bg"><select name="gender" id="gender" class="register_monthday_selection">
<option value="">Select an option</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select></td>
<div class="errormsg errpass6" id="error_gender" style="display:none;"><span class="noberr"></span><span id="error_gender_val">Please Select Gender</div>
</tr>
<tr>
<td align="right" class="registerpage_form_credential">Select an Avatar:</td>
<td colspan="3" class="registersignupbox_bg"><input type="file" id="image" name="userAvatar" /></td>
<div class="errormsg errpass7" id="error_image" style="display:none;"><span class="noberr"></span><span id="error_image_val">Please Select Image</div>
</tr>
<tr>
<td colspan="4" style="
padding-left: 37%;
"><div class="g-recaptcha" data-sitekey="6LfhvAkTAAAAAFQyqmN2nf9hXEY1T0jF89SCGNVB"></div>
</td>
</tr>
</table></td>
<td width="455">
<p>
<iframe width="555" height="312" src="https://www.youtube.com/embed/vkjFm6ClTuw" frameborder="0" allowfullscreen></iframe>
</p>
<br />
<div style="width:468px ;margin: 0 auto; height:60px">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Header/Footer Small -->
<ins class="adsbygoogle"
style="display:inline-block;width:468px;height:60px"
data-ad-client="ca-pub-5794587985510139"
data-ad-slot="5064971004"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</td>
</tr>
<tr>
<td colspan="2"><table width="709" border="0" align="center" cellpadding="2" cellspacing="2" style="margin-top:11px; margin-top: 15px !important;
margin-right: 67px;" class="signp">
<tr>
<td> </td>
<td class="contactus_form_credentials"> </td>
</tr>
<tr>
<td width="21" align="center"><label>
<input type="checkbox" name="promotion" id="promotion"/>
</label></td>
<td width="442" class="contactus_form_credentials">I agree that my account will be deleted if my email is not valid</td>
</tr>
<tr>
<td align="center"><input type="checkbox" name="checkbox2" id="checkbox2"/></td>
<td class="contactus_form_credentials">I have read and agree to the (example.com) <a href="terms.php" class="termsofuse">Terms of use</a></td>
</tr>
<tr>
<td> </td>
<td style="cursor:pointer;" onclick="registerFormValidation();"><img src="images/register_signup_btn.png" width="220" height="108" /></td>
</tr>
</table></td>
</tr>
</table>
<div class="errormsg errpass7" id="error_captcha" style="display:none;"><span class="noberr"></span><span id="error_captcha_val"></div>
</form>
这是注册函数
function insertData($arr,$files){
$username =$arr['userName'];
$pass =$arr['userPassword'];
$realname =$arr['userRealName'];
$email =$arr['userEmail'];
$country =$arr['country'];
$gender =$arr['gender'];
$dob =$arr['userDay'].'-'.$arr['userMonth'].'-'.$arr['userYear'];
if(self::userNameExit($username) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
if(self::userEmailExist($email) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
require_once(COMM_PATH."DatabaseManager.php");
$db= new DatabaseManager();
$emailcode = rand().time();
$sql = "Insert into users(username,pass,realname,email,country,dob,gender,lastlogin,register_date,email_varification,email_code)values('".$username."','".md5($pass)."','".$realname."','".$email."','".$country."','".$dob."','".$gender."', now(), now(),'n','".$emailcode."')";
$result = $db->executeUpdate($sql);
$user_id = $db->lastInsertId();
self::autoFriends($user_id);
self::sentMessage($user_id,$username);
insertStatusNow($user_id,"user");
if(isset($files['userAvatar']['name']) && $files['userAvatar']['name'] !=""){
$nameOfImage = time()."_".basename($files['userAvatar']['name']);
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
}
我想知道我怎么了,网站被黑了,生意每天都在下降
更新::
if(isset($files['userAvatar']['name']) && $files['userAvatar']['name'] !=""){
$nameOfImage = $files['userAvatar']['name'];
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(in_array($fileType = $fileInfo->file($nameOfImage, FILEINFO_MIME_TYPE, $allowedMIMETypes))){
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
else {
die("check you reg");
}
return null;
我已经制作了这样的代码,但它允许用户注册但没有照片
所以你想要的是人们只上传图片而不是 PHP 脚本。那么答案很简单,检查文件扩展名。但话虽这么说,还是有一些方法,比如注入 %00
(不确定操作码)来欺骗 PHP 服务器。最好获得一个现有的图书馆来为您检查。一旦完成,为了不执行上传的脚本,不要给它执行权限。这样即使攻击者上传 php 文件,它也不会被您的服务器处理。如果你正确检查扩展,当攻击者假设上传 c99 shell 时,只会在上传路径中看到损坏的图像,而不是实际的 shell 页面,因为它正在通过图像网络服务器
使用它来检查文件的 MIME 类型:
$file = $files['userAvatar']['name'];
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(in_array($fileType = $fileInfo->file($file, FILEINFO_MIME_TYPE, $allowedMIMETypes)){
//the file is an image
} else {
//file doesn't have a whitelisted MIME-type
}
更新: 如果你想阻止用户在没有头像的情况下注册,只需在将用户插入数据库之前输入我给你的代码即可。你的整个函数会变成这样:
function insertData($arr,$files){
$username =$arr['userName'];
$pass =$arr['userPassword'];
$realname =$arr['userRealName'];
$email =$arr['userEmail'];
$country =$arr['country'];
$gender =$arr['gender'];
$dob =$arr['userDay'].'-'.$arr['userMonth'].'-'.$arr['userYear'];
if(self::userNameExit($username) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
if(self::userEmailExist($email) != "not_exist"){
echo "<script>document.location.href='".HTTP_PATH."register.php'</script>";
exit();
}
//*************
if(!isset($files['userAvatar']['name']) || empty($files['userAvatar']['name'])){
//no file was uploaded, give some kind of error message
}
$fileInfo = new finfo();
$allowedMIMETypes = ['image/bmp', 'image/gif', 'image/jpeg', 'image/png']; //the most common image MIME types, you can add more if you want
if(!in_array($fileType = $fileInfo->file($nameOfImage, FILEINFO_MIME_TYPE, $allowedMIMETypes))){
//the uploaded file wasn't recognized as an image, give some kind of error message
}
*************//
require_once(COMM_PATH."DatabaseManager.php");
$db= new DatabaseManager();
$emailcode = rand().time();
$sql = "Insert into users(username,pass,realname,email,country,dob,gender,lastlogin,register_date,email_varification,email_code)values('".$username."','".md5($pass)."','".$realname."','".$email."','".$country."','".$dob."','".$gender."', now(), now(),'n','".$emailcode."')";
$result = $db->executeUpdate($sql);
$user_id = $db->lastInsertId();
self::autoFriends($user_id);
self::sentMessage($user_id,$username);
insertStatusNow($user_id,"user");
$nameOfImage = time()."_".basename($files['userAvatar']['name']);
$path = USER_IMAGE_UPLOAD_PATH.$nameOfImage;
if(move_uploaded_file($files['userAvatar']['tmp_name'], $path)){
$sql="UPDATE `users` SET `image` = '".$nameOfImage."' WHERE `Id` =".$user_id;
$db->executeUpdate($sql);
if(isset($arr['promotion']) && $arr['promotion'] == "promotion_yes"){
self::notificationSubmit($user_id,$email);
}
}
return $user_id;
}
此外,我看到您通过使用 JavaScrip 将用户重定向到注册页面来处理错误(甚至没有使用 PHP
header()
函数)。这不是很优雅,用户不会知道他们做错了什么,所以我建议您 return 来自该函数的错误消息,然后在注册页面上回显