【发布时间】:2017-10-18 00:40:01
【问题描述】:
编辑2:我注意到用户可以上传无限的文件并且可以占用所有磁盘空间,如何防止这种情况?
编辑:因为没有人回答这个问题,有没有我可以阅读的资料来得到我的答案???
我有一个联系表格。有三个输入。我使用了一个 jQuery 插件来上传文件。 This插件添加了另一个表单元素并通过ajax上传文件。
我是初学者,但这段代码是为客户和真正的工作而设计的,所以我想确保它是安全的!
在我看来:
<form action="" method="post" enctype="multipart/form-data" >
<input type="text" name="name" />
<input type="number" name="phone" />
<textarea name="enquiry" rows="10" ></textarea>
<div id="upload-div">
<div id="extraupload">Upload</div>
<input type="hidden" name="count" value="0" id="count"/>
<input type="submit" />
$(document).ready(function()
{
var uploadObj = $("#extraupload").uploadFile({
url:"/uplod_url",
fileName:"file",
onSuccess:function(files,data,xhr,pd)
{
data = jQuery.parseJSON(data);
if(data.status == 'success') {
var count = $('#count').val() * 1 + 1;
for(var i=0; i<data.files.length; i++) {
$('<input type="hidden" name="file_'+count+'" value="'+data.files[i]+'">').insertBefore('#extraupload');
$('#count').val(count);
count++;
}
}
},
});
});
</script>
每次上传成功,input count值加一
并将使用上传的文件名的值附加一个隐藏的输入。
在 php 中,我检查文件类型并更改文件名:
上传_url.php:
if ($_FILES['file']['type']=='image/jpeg' || $_FILES['file']['type']=='image/pjpeg') {
$ext = '.jpg';
}
elseif ($_FILES['file']['type']=='image/png') {
$ext = '.png';
}
elseif ($_FILES['file']['type']=='application/pdf') {
$ext = '.pdf';
}
else {
echo json_encode('Only images and pdf files are allowed!');
die();
}
$fileName = md5(uniqid());
$fileName = $fileName.$ext;
move_uploaded_file($_FILES["file"]["tmp_name"], 'image/tmp'.$fileName);
$result = array('status'=> 'success','files' => $fileName);
echo json_encode($result);
将文件名更改为唯一哈希后,我将其保存在 tmp 文件夹中。
那么当主表单被提交时,会发生这样的事情:
//validation method: if that file exists in tmp folder
if(isset($this->request->post['count']) && is_numeric($this->request->post['count'])) {
for($i=1; $i<=$this->request->post['count']; $i++ ) {
if(isset($this->request->post['file_'.$i])){
if(!file_exists('image/tmp/'.$this->request->post['file_'.$i])){
//throw error
}
} else{
//throw error
}
}
}
// hidden input count can only be integer
if(isset($this->request->post['count']) && !is_numeric($this->request->post['count'])) {
//throw error
}
然后邮寄文件并将文件名保存在数据库中(我没有包括数据库部分,因为我有点确定它没问题)
//by every submition delete files in tmp folder older than 1 day
$oldFiles = glob($tmp_dir."*");
$now = time();
foreach ($oldFiles as $oldFile) {
if (is_file($oldFile)) {
if ($now - filemtime($oldFile) >= 60 * 60 * 24) {
unlink($oldFile);
}
}
}
$mail = new Mail();
//Mail Setting and details deleted
//if there's any file uploaded
if($this->request->post['count'] != 0) {
//unique directory for every form submition
$dir_path = 'image/submitted/'.uniqid();
mkdir($dir_path, 0764, true);
//for all hidden inputs move file from tmp folder to $dir_path
for ($i=1; $i <= $this->request->post['count']; $i++) {
$file = $this->request->post['file_'.$i];
rename('image/tmp'.$file, $dir_path.'/'.$file);
$mail->AddAttachment($dir_path.'/'.$file);
}
}
$mail->send();
现在我的问题是:这样安全吗?特别是当我使用文件名附加隐藏输入并从隐藏输入计数中获取上传文件的数量时?
此代码已经有效,但我认为这可能是一个安全问题。
非常感谢您的耐心等待,并为我糟糕的英语感到抱歉!
ps:我用的是opencart
【问题讨论】:
标签: php ajax forms security upload