Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何保护此图像上载代码_Php_Mysql_Security_File Upload_Image Uploading - Fatal编程技术网

Php 如何保护此图像上载代码

Php 如何保护此图像上载代码,php,mysql,security,file-upload,image-uploading,Php,Mysql,Security,File Upload,Image Uploading,我在过去两周内被黑客攻击,我在日志文件中看到,黑客可以在注册时上传php外壳 function insertData($arr,$files){ $username =$arr['userName']; $pass =$arr['userPassword']; $realname =$arr['userRealName']; $email =$arr['userEmail']; $country =$arr['country'];

我在过去两周内被黑客攻击,我在日志文件中看到,黑客可以在注册时上传php外壳

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;
    }
}
这是一个让用户注册并将数据保存到网站数据库的表单,关键是当他上传他的头像时,他可以上传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" />&nbsp;</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" />&nbsp;</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" />&nbsp;</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" />
&nbsp;</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" />
&nbsp;</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>
&nbsp;</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>&nbsp;</td>
<td class="contactus_form_credentials">&nbsp;</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>&nbsp;</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> 

我已经编写了这样的代码,但它允许用户注册,但没有照片,所以你想要的是人们只上传图像,而不是PHP脚本。答案很简单,检查文件扩展名。但是也有一些方法,比如注入
%00
(不确定操作码)来愚弄PHP服务器。最好是找到一个现有的库来为您检查。一旦完成,为了使上传的脚本不被执行,不要给它可执行的权利。这样,即使攻击者上载php文件,您的服务器也不会处理该文件。如果正确检查扩展名,当攻击者假设上载c99外壳时,将只在上载路径中看到损坏的图像,而不会看到实际的外壳页面,因为web服务器正在读取图像,请使用此选项检查文件的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;
}
函数插入数据($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::usernamexit($username)!=“不存在”){
echo“document.location.href=”.HTTP_PATH。“register.php';
退出();
}
if(self::userEmailExist($email)!=“not_exist”){
echo“document.location.href=”.HTTP_PATH。“register.php';
退出();
}
//*************
如果(!isset($files['userAvatar']['name'])| |为空($files['userAvatar']['name'])){
//未上载任何文件,请给出某种错误消息
}
$fileInfo=new finfo();
$allowedMIMETypes=['image/bmp'、'image/gif'、'image/jpeg'、'image/png'];//最常见的图像MIME类型,如果需要,可以添加更多
如果(!在数组中($fileType=$fileInfo->file($nameOfImage,fileInfo\u MIME\u TYPE,$allowedMIMETypes))){
//上载的文件无法识别为图像,请给出某种错误消息
}
*************//
require_once(COMM_PATH.“DatabaseManager.php”);
$db=新数据库管理器();
$emailcode=rand().time();
$sql=“在用户(用户名、密码、实名、电子邮件、国家/地区、出生日期、性别、上次登录、注册日期、电子邮件变量、电子邮件代码)中插入值(“$username.”、“.md5($pass.”、“$realname.”、“$email.”、“$country.”、“$dob.”、“$gender.”、now()、now()、“$n.”、“$emailcode.”);
$result=$db->executeUpdate($sql);
$user_id=$db->lastInsertId();
self::autoFriends($user\u id);
self::sentMessage($user\u id,$username);
insertStatusNow($user_id,“user”);
$nameOfImage=time();
$path=用户\图像\上传\路径。$nameOfImage;
如果(移动上传的文件($files['userAvatar']['tmp\u name'],$path)){
$sql=“UPDATE`users`SET`image`='”$nameOfImage。“”其中`Id`=”$user\u Id;
$db->executeUpdate($sql);
如果(isset($arr['promotion'])和&$arr['promotion']==“promotion\u yes”){
self::notificationSubmit($user\u id,$email);
}
}
返回$user\u id;
}

此外,我看到您通过使用JavaScrip(甚至不使用
PHP
函数)将用户重定向到注册页面来处理错误。这不是很优雅,用户也不知道他们做错了什么,因此我建议您从函数返回一条错误消息,然后在注册页面上回显该消息

在将HTML内容插入数据库之前,您在哪里剥离HTML内容?使用PDO prepare语句:在PHP7中它不会贬值。任何人都可以简单地将用户名设置为,例如:
alert(“xss”)可能重复的@KyleE4K不是sql注入,而是文件上载漏洞。假设攻击者上载c99.php。然后,当他转到该路径时,服务器将运行php脚本,从而给他一个shell访问权限。这里还有更多内容,我看不到对代码中的输入进行清理。另外,为什么不限制文件扩展名(创建一个对象),它搜索文件扩展名名称,并使用回调方法切换是否可以接受?很好,它起到了作用,但如果我问得更多,我很抱歉。你有没有办法阻止上传像image.php.jpg这样的文件?感谢you@PetterAdam这段代码不检查文件扩展名,而是检查MIME类型,因此即使黑客上传一个名为image.php.jpg的php文件,它也不会被识别为jpg图像,并且会显示一条错误消息fire@PetterAdam图像上传部分是。然而,正如KyleE4K所评论的,您的代码仍然非常容易被SQL注入。可以使用准备好的语句解决此问题-请在此处阅读有关此问题的更多信息:
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;
}