我的一个托管空间的网站昨天遭到攻击,黑客通过电子邮件告诉我,一个产品图像被另一个图像文件更改了。这是真的,因为他把他的签名放在旧图像上(文件替换)。 在这个上传脚本中有一些安全漏洞吗?
<?php ini_set("memory_limit", "200000000"); // for large images so that we do not get "Allowed memory exhausted"?>
<?php
include_once("configlogin.php");
include("funz.php");
// Check user logged in already:
checkLoggedIn("yes");
// upload the file
if ((isset($_POST["submitted_form"])) && ($_POST["submitted_form"] == "image_upload_form")) {
$idimg=$_POST['idimg'];
// file needs to be jpg,gif,bmp,x-png and 4 MB max
if (($_FILES["image_upload_box"]["type"] == "image/jpeg") && ($_FILES["image_upload_box"]["size"] < 4000000))
{
// QUI SCELGO LA DIMENSIONE FINALE DELL'IMMAGINE AL RESIZE
$max_upload_width = 800;
$max_upload_height = 600;
// if user chosed properly then scale down the image according to user preferances
if(isset($_REQUEST['max_width_box']) and $_REQUEST['max_width_box']!='' and $_REQUEST['max_width_box']<=$max_upload_width){
$max_upload_width = $_REQUEST['max_width_box'];
}
if(isset($_REQUEST['max_height_box']) and $_REQUEST['max_height_box']!='' and $_REQUEST['max_height_box']<=$max_upload_height){
$max_upload_height = $_REQUEST['max_height_box'];
}
// if uploaded image was JPG/JPEG
if($_FILES["image_upload_box"]["type"] == "image/jpeg" || $_FILES["image_upload_box"]["type"] == "image/pjpeg"){
$image_source = imagecreatefromjpeg($_FILES["image_upload_box"]["tmp_name"]);
}
// if uploaded image was GIF
if($_FILES["image_upload_box"]["type"] == "image/gif"){
$image_source = imagecreatefromgif($_FILES["image_upload_box"]["tmp_name"]);
}
// BMP doesn't seem to be supported so remove it form above image type test (reject bmps)
// if uploaded image was BMP
if($_FILES["image_upload_box"]["type"] == "image/bmp"){
$image_source = imagecreatefromwbmp($_FILES["image_upload_box"]["tmp_name"]);
}
// if uploaded image was PNG
if($_FILES["image_upload_box"]["type"] == "image/x-png"){
$image_source = imagecreatefrompng($_FILES["image_upload_box"]["tmp_name"]);
}
$remote_file = "../immaginiprodotti/".$_FILES["image_upload_box"]["name"];
imagejpeg($image_source,$remote_file,100);
chmod($remote_file,0644);
// get width and height of original image
list($image_width, $image_height) = getimagesize($remote_file);
if($image_width>$max_upload_width || $image_height >$max_upload_height){
$proportions = $image_width/$image_height;
if($image_width>$image_height){
$new_width = $max_upload_width;
$new_height = round($max_upload_width/$proportions);
}
else{
$new_height = $max_upload_height;
$new_width = round($max_upload_height*$proportions);
}
$new_image = imagecreatetruecolor($new_width , $new_height);
$image_source = imagecreatefromjpeg($remote_file);
imagecopyresampled($new_image, $image_source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);
imagejpeg($new_image,$remote_file,100);
imagedestroy($new_image);
}
imagedestroy($image_source);
rename ($remote_file, "../immaginiprodotti/$idimg.jpg");
header("Location: prodotti.php");
exit;
}
else{
header("Location: prodotti.php");
exit;
}
}
?>
checkPass($login, $password) {
$login= mysql_real_escape_string($login);
$password= mysql_real_escape_string($password);
$login=addslashes($login);
$password=addslashes($password);
global $link;
$query="SELECT login, password FROM users WHERE login='$login' and password='$password'";
$result=mysql_query($query, $link)
or die("checkPass fatal error: ".mysql_error());
// Check exactly one row is found:
if(mysql_num_rows($result)==1 AND !preg_match("[a-z0-9]", $login) AND !preg_match("[a-z0-9]", $password ) ) {
$row=mysql_fetch_array($result);
return $row;
}
//Bad Login:
return false;
} // end func checkPass($login, $password)
脚本的第二部分是登录控制功能(来自包含的配置文件) 也可以通过sql-injection绕过这个checkPass()函数直接进入上传保护页面?
感谢名单
答案 0 :(得分:2)
您的代码非常不安全。您 DIRECTLY 使用 USER-SUPPLIED 文件名作为目标“写入此文件”名称。用户在那里指定完整路径是TRIVIAL,您的代码将很乐意在他们想要的服务器上任意编写他们的图像:
$remote_file = "../immaginiprodotti/".$_FILES["image_upload_box"]["name"];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
imagejpeg($image_source,$remote_file,100);
e.g。考虑有人假装上传并做相当于
image_upload_box['name'] = '../../../../../../home/sites/example.com/imgs/site-logo.jpg';
您也容易受到sql injection attacks的攻击:
此行使密码“安全”:
$password= mysql_real_escape_string($password);
由于某些未知原因你使用addslashes()来解决字符串:
$password=addslashes($password);
重新打开注入漏洞。 addslashes()是完全没用的蠢垃圾。你应该通过手术从你的大脑中删除它存在的任何知识。它不是unicode-aware,并且允许注入攻击。
除此之外,mysql _ *()函数已过时/弃用,您应该废弃所有这些代码,并使用mysqli(请注意i
)或PDO从头开始,使用适当的预处理语句和占位符。
您的preg_match()
电话也不正确,使整个正则表达式无用。您还尝试在完成addlashes之后进行正则表达式测试,这意味着像Miles O'Brien
这样的正确名称会被拒绝,因为addlashes / real_escape_string会将其变为Miles O\\'Brien
并被拒绝。 / p>