提问¶
问题1:上传漏洞是怎么产生的?
问题2:是否可以只用js判断文件类型而php不判断?
问题3:为什么必须用move_uploaded_file?
课程单元¶
一个简单的文件上传例子
文件上传漏洞是怎么产生的
如何避免文件上传漏洞
1. 一个简单的文件上传例子¶
这是一个简单的上传文件的html代码。
<form action="upload.php" method="post" enctype="multipart/form-data">
选择一个文件:<input type="file" name="file" /><br />
<input type="submit" value="上传" />
</form>
这是一个简单的上传文件的php代码。
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
if(move_upload_file($_FILES['file']['tmp_name']), $uploadfile)){
echo "文件上传成功";
}
else{
echo "文件上传失败";
}
2. 文件上传漏洞是怎么产生的¶
上面的文件上传的例子,没有对被上传的文件进行任何判断,这样用户可以上传一个.php文件,然后通过浏览器访问该php文件,来达到攻击的目的。
3. 如何避免文件上传漏洞¶
1、js判断允许上传的文件类型
2、php判断允许上传的文件类型
3、使用move_uploaded_file
4、web服务器增加配置
3.1. JS判断上传的文件类型¶
在客户端提交文件上传之前,判断只允许上传指定类型的文件。
<script type="text/javascript">
function checkform(){
var filename = uploadform.file.value;
var fileext = filename.substring(filename.length - 4, filename.length);
if(fileext != '.jpg'){
alert('文件类型必须为jpg!');
return false;
}
return true;
}
</script>
<form action="upload.php" method="post" enctype="multipart/form-data" onsubmit="return checkform();">
选择一个文件:<input type="file" name="file" /><br />
<input type="submit" value="上传" />
</form>
3.2. php判断上传的文件类型¶
在文件上传后,判断上传的文件类型,如果类型不对,则不执行上传操作。
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
$fileext = strtolower(end(explode('.', $uploadfile)));
if($fileext != '.jpg'){
echo '文件类型必须为jpg!';
die();
}
if(move_upload_file($_FILES['file']['tmp_name']), $uploadfile)){
echo "文件上传成功";
}
else{
echo "文件上传失败";
}
3.3. 使用move_uploaded_file¶
bool move_uploaded_file ( string $filename , string $destination )
本函数检查并确保由 filename 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST 上传机制所上传的)。如果文件合法,则将其移动为由 destination 指定的文件。
在执行文件上传操作时,都必须用这个函数来移动上传的临时文件到正式目录下,而不能自己使用move方法来移动。
3.4. web服务器增加配置¶
可以在web服务器中,配置保存上载的目录不能执行php文件,这样万一js或者php判断都不严谨,也不会出现问题。
apache服务器配置不能执行php文件
<Location /uploads>
AddType application/x-httpd-php-source .php
</Location>