安全优化

feat/task1-c-wallet
gongfuxiang 2025-03-12 20:57:10 +08:00
parent e3b193d991
commit 4a0b962883
6 changed files with 148 additions and 31 deletions

View File

@ -26,6 +26,7 @@ class Email
private $expire_time;
private $key_code;
private $is_frq;
private $is_log;
public $error;
private $obj;
@ -39,6 +40,7 @@ class Email
* @param [int] $params['expire_time'] [到期时间默认30单位]
* @param [string] $params['key_prefix'] [验证码种存储前缀key默认 空)]
* @param [string] $params['is_frq'] [是否验证频率(默认 是)]
* @param [string] $params['is_log'] [是否记录日志(默认 是)]
*/
public function __construct($params = [])
{
@ -46,6 +48,7 @@ class Email
$this->expire_time = isset($params['expire_time']) ? intval($params['expire_time']) : 30;
$this->key_code = isset($params['key_prefix']) ? trim($params['key_prefix']).'_sms_code' : '_sms_code';
$this->is_frq = isset($params['is_frq']) ? intval($params['is_frq']) : 1;
$this->is_log = isset($params['is_log']) ? intval($params['is_log']) : 1;
}
/**
@ -168,11 +171,14 @@ class Email
$this->obj->AltBody = strip_tags($params['content']);
// 添加短信日志
$log = EmailLogService::EmailLogAdd($this->obj->Host, $this->obj->Port, $this->obj->Username, $this->obj->From, $this->obj->FromName, $params['email'], $params['title'], $params['content'], $params_code);
if($log['code'] != 0)
{
$this->error = $log['msg'];
return false;
if($this->is_log == 1)
{
$log = EmailLogService::EmailLogAdd($this->obj->Host, $this->obj->Port, $this->obj->Username, $this->obj->From, $this->obj->FromName, $params['email'], $params['title'], $params['content'], $params_code);
if($log['code'] != 0)
{
$this->error = $log['msg'];
return false;
}
}
// 发送邮件
@ -185,13 +191,20 @@ class Email
}
// 日志回调
EmailLogService::EmailLogResponse($log['data']['id'], 1, time()-$log['data']['add_time']);
if($this->is_log == 1)
{
EmailLogService::EmailLogResponse($log['data']['id'], 1, time()-$log['data']['add_time']);
}
return true;
} else {
$this->error = $this->obj->ErrorInfo;
// 日志回调
EmailLogService::EmailLogResponse($log['data']['id'], 2, time()-$log['data']['add_time'], $this->error);
if($this->is_log == 1)
{
EmailLogService::EmailLogResponse($log['data']['id'], 2, time()-$log['data']['add_time'], $this->error);
}
}
return false;
}

View File

@ -79,22 +79,30 @@ class FileUpload
}
$info = getimagesize($temp_file);
if(stripos($original_name, '.') === false)
if(!empty($info) && !empty($info['mime']))
{
$original_name .= str_replace('/', '.', $info['mime']);
}
// 图片文件
if(isset($params['data_type']) && $params['data_type'] == 'images')
{
// 验证一句话木马(如果是加密的无法判断)
$content = @file_get_contents($temp_file);
if(false == $content || preg_match('#<\?php#i', $content) || $info['mime'] == 'text/x-php')
// 文件原始为空泽使用类型作为名称
if(empty($original_name) && stripos($original_name, '.') === false)
{
$original_name .= str_replace('/', '.', $info['mime']);
}
// 是否php文件类型
if($info['mime'] == 'text/x-php')
{
return DataReturn(MyLang('common_extend.base.fileupload.file_illegal_tips'), -1);
}
}
// 安全验证
if(!isset($params['is_security_check']) || $params['is_security_check'] == 1)
{
$ret = \base\FileUtil::FileContentSecurityCheck($temp_file);
if($ret['code'] != 0)
{
return $ret;
}
}
// 后缀名称
$ext_all = explode('.', $original_name);
$ext = $ext_all[count($ext_all)-1];

View File

@ -375,5 +375,38 @@ class FileUtil
}
return false;
}
/**
* 上传文件内容安全验证
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2025-03-09
* @desc description
* @param [string] $value [文件内容,临时地址]
* @param [boolean] $is_temp_file [是否为临时地址]
*/
public static function FileContentSecurityCheck($value, $is_temp_file = true)
{
if(!empty($value))
{
// 临时文件读取
if($is_temp_file)
{
$value = @file_get_contents($value);
}
// 包含php代码
// 包含script脚本
// 包含src引入文件
// 包含href跳转地址
// 包含iframe引入外部地址
if(preg_match('#<\?php#i', $value) || preg_match('#<script#i', $value) || preg_match('#src=#i', $value) || preg_match('#href=#i', $value) || preg_match('#<iframe#i', $value))
{
return DataReturn(MyLang('common_extend.base.fileupload.file_illegal_tips'), -1);
}
}
return DataReturn('success', 0);
}
}
?>

View File

@ -229,8 +229,16 @@ class Images
$type = $this->Is_ImageType($img_info['mime']);
if($type == 'no') continue;
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($data[$i], false);
if($ret['code'] != 0)
{
continue;
}
// 存储文件
$file_name = $this->GetNewFileName().'.'.$type;
if(file_put_contents($this->i_path.$file_name, $data) !== false) $this->i_data[] = $file_name;
if(file_put_contents($this->i_path.$file_name, $data[$i]) !== false) $this->i_data[] = $file_name;
}
return $this->i_data;
}
@ -249,12 +257,20 @@ class Images
public function GetOriginal($data, $path)
{
if(!$this->Initialization($data, $path)) return '';
if(empty($data['tmp_name'])) return '';
// 是否图片类型
$type = $this->Is_ImageType($data['type']);
if($type == 'no') return '';
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($data['tmp_name']);
if($ret['code'] != 0)
{
return '';
}
// 存储文件
$file_name = $this->GetNewFileName().'.'.$type;
return move_uploaded_file($data['tmp_name'], $this->i_path.$file_name) ? $file_name : '';
}
@ -345,6 +361,13 @@ class Images
*/
private function ImageCompress($width, $height, $file, $type, $path, $src_x = 0, $src_y = 0, $src_width = 0, $src_height = 0)
{
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($file);
if($ret['code'] != 0)
{
return false;
}
// 获取图片原本尺寸
list($w, $h) = getimagesize($file);
@ -481,6 +504,7 @@ class Images
$file_name = $this->GetNewFileName().'.jpg';
}
// 下载文件
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
@ -488,6 +512,14 @@ class Images
$file = curl_exec($ch);
curl_close($ch);
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($file, false);
if($ret['code'] != 0)
{
return '';
}
// 存储文件
if(file_put_contents($this->i_path.$file_name, $file) !== false)
{
return $file_name;

View File

@ -35,6 +35,7 @@ class Sms
private $expire_time;
private $key_code;
private $is_frq;
private $is_log;
/**
* 构造方法
@ -46,6 +47,7 @@ class Sms
* @param [int] $params['expire_time'] [到期时间默认30单位]
* @param [string] $params['key_prefix'] [验证码种存储前缀key默认 空)]
* @param [string] $params['is_frq'] [是否验证频率(默认 是)]
* @param [string] $params['is_log'] [是否记录日志(默认 是)]
*/
public function __construct($params = [])
{
@ -53,6 +55,7 @@ class Sms
$this->expire_time = isset($params['expire_time']) ? intval($params['expire_time']) : 30;
$this->key_code = isset($params['key_prefix']) ? trim($params['key_prefix']).'_sms_code' : '_sms_code';
$this->is_frq = isset($params['is_frq']) ? intval($params['is_frq']) : 1;
$this->is_log = isset($params['is_log']) ? intval($params['is_log']) : 1;
$this->sign_ame = MyC('common_sms_sign');
$this->access_key_id = MyC('common_sms_apikey');
@ -205,11 +208,14 @@ class Sms
$request_params['Signature'] = $this->ComputeSignature($request_params, $this->access_key_secret);
// 添加短信日志
$log = SmsLogService::SmsLogAdd('aliyun', $mobile, $sign_name, $template_value, $template_var, $request_url, $request_params);
if($log['code'] != 0)
if($this->is_log == 1)
{
$this->error = $log['msg'];
return false;
$log = SmsLogService::SmsLogAdd('aliyun', $mobile, $sign_name, $template_value, $template_var, $request_url, $request_params);
if($log['code'] != 0)
{
$this->error = $log['msg'];
return false;
}
}
// 远程请求
@ -226,14 +232,23 @@ class Sms
if(isset($result['Code']) && $result['Code'] == 'OK')
{
// 日志回调
SmsLogService::SmsLogResponse($log['data']['id'], 1, $result, time()-$log['data']['add_time']);
if($this->is_log == 1)
{
SmsLogService::SmsLogResponse($log['data']['id'], 1, $result, time()-$log['data']['add_time']);
}
return true;
}
// 错误原因
$this->error = $this->GetErrorMessage($result['Code']);
// 日志回调
SmsLogService::SmsLogResponse($log['data']['id'], 2, $result, time()-$log['data']['add_time'], $this->error);
if($this->is_log == 1)
{
SmsLogService::SmsLogResponse($log['data']['id'], 2, $result, time()-$log['data']['add_time'], $this->error);
}
return false;
}

View File

@ -134,6 +134,14 @@ class Uploader
return;
}
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($this->file['tmp_name']);
if($ret['code'] != 0)
{
$this->stateInfo = $ret['msg'];
return;
}
//移动文件
if (!(move_uploaded_file($this->file['tmp_name'], $this->filePath) && file_exists($this->filePath))) { //移动失败
$this->stateInfo = $this->getStateErrorInfo('error_file_move');
@ -204,14 +212,21 @@ class Uploader
return;
}
// 验证一句话木马(如果是加密的无法判断)
$content = @file_get_contents($this->file['tmp_name']);
if(false == $content || preg_match('#<\?php#i', $content) || $info['mime'] == 'text/x-php')
// 是否php文件类型
if($info['mime'] == 'text/x-php')
{
$this->stateInfo = $this->getStateErrorInfo('invalid_file');
return;
}
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($this->file['tmp_name']);
if($ret['code'] != 0)
{
$this->stateInfo = $ret['msg'];
return;
}
// 是否需要直接存储文件
if(!move_uploaded_file($this->file['tmp_name'], $this->filePath))
{
@ -332,10 +347,11 @@ class Uploader
$this->fileName = $this->getFileName();
$dirname = dirname($this->filePath);
// 验证一句话木马(如果是加密的无法判断)
if(preg_match('#<\?php#i', $reponse))
// 安全验证
$ret = \base\FileUtil::FileContentSecurityCheck($reponse, false);
if($ret['code'] != 0)
{
$this->stateInfo = $this->getStateErrorInfo('invalid_file');
$this->stateInfo = $ret['msg'];
return;
}