|
@@ -17,6 +17,9 @@ class BaseController extends PublicController
|
|
|
|
|
|
|
|
public function beforeAction($action)
|
|
public function beforeAction($action)
|
|
|
{
|
|
{
|
|
|
|
|
+ // 新增:全局安全检查
|
|
|
|
|
+ $this->securityCheck();
|
|
|
|
|
+
|
|
|
//6表示总后台
|
|
//6表示总后台
|
|
|
Yii::$app->params['ptStyle'] = 6;
|
|
Yii::$app->params['ptStyle'] = 6;
|
|
|
$staffId = jwt::getLoginId();
|
|
$staffId = jwt::getLoginId();
|
|
@@ -65,4 +68,185 @@ class BaseController extends PublicController
|
|
|
return parent::beforeAction($action);
|
|
return parent::beforeAction($action);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 全局安全检查
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function securityCheck()
|
|
|
|
|
+ {
|
|
|
|
|
+ $request = Yii::$app->request;
|
|
|
|
|
+ $this->checkSuspiciousParameters($request);
|
|
|
|
|
+ $this->checkFileUploadSecurity($request);
|
|
|
|
|
+ $this->checkSqlInjection($request);
|
|
|
|
|
+ $this->checkXssAttack($request);
|
|
|
|
|
+ $this->logSecurityActivity($request);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查可疑参数
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function checkSuspiciousParameters($request)
|
|
|
|
|
+ {
|
|
|
|
|
+ $dangerousPatterns = [
|
|
|
|
|
+ // 代码执行相关
|
|
|
|
|
+ '/eval\s*\(/i',
|
|
|
|
|
+ '/exec\s*\(/i',
|
|
|
|
|
+ '/system\s*\(/i',
|
|
|
|
|
+ '/passthru\s*\(/i',
|
|
|
|
|
+ '/shell_exec\s*\(/i',
|
|
|
|
|
+ '/proc_open\s*\(/i',
|
|
|
|
|
+ '/popen\s*\(/i',
|
|
|
|
|
+
|
|
|
|
|
+ // 文件操作相关
|
|
|
|
|
+ '/file_put_contents\s*\(/i',
|
|
|
|
|
+ '/file_get_contents\s*\(/i',
|
|
|
|
|
+ '/fwrite\s*\(/i',
|
|
|
|
|
+ '/fopen\s*\(/i',
|
|
|
|
|
+
|
|
|
|
|
+ // 目录遍历
|
|
|
|
|
+ '/\.\.\//',
|
|
|
|
|
+ '/\.\.\\\/',
|
|
|
|
|
+
|
|
|
|
|
+ // 模板注入
|
|
|
|
|
+ '/<\?php/i',
|
|
|
|
|
+ '/<\?=/i',
|
|
|
|
|
+ '/<\?/i',
|
|
|
|
|
+
|
|
|
|
|
+ // 序列化攻击
|
|
|
|
|
+ '/O:\d+:/',
|
|
|
|
|
+ '/a:\d+:/',
|
|
|
|
|
+ '/s:\d+:/',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ foreach (['get', 'post'] as $method) {
|
|
|
|
|
+ $params = $request->$method();
|
|
|
|
|
+ foreach ($params as $key => $value) {
|
|
|
|
|
+ if (is_string($value)) {
|
|
|
|
|
+ foreach ($dangerousPatterns as $pattern) {
|
|
|
|
|
+ if (preg_match($pattern, $value)) {
|
|
|
|
|
+ $this->logSecurityViolation($request, "Dangerous pattern detected: $pattern in $key");
|
|
|
|
|
+ throw new \yii\web\HttpException(403, 'Access denied');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查文件上传安全
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function checkFileUploadSecurity($request)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!empty($_FILES)) {
|
|
|
|
|
+ foreach ($_FILES as $file) {
|
|
|
|
|
+ if (isset($file['name'])) {
|
|
|
|
|
+ $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
|
|
|
|
+ $allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];
|
|
|
|
|
+ if (!in_array($ext, $allowed)) {
|
|
|
|
|
+ $this->logSecurityViolation($request, "Illegal file upload: " . $file['name']);
|
|
|
|
|
+ throw new \yii\web\HttpException(403, 'Illegal file type');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查SQL注入
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function checkSqlInjection($request)
|
|
|
|
|
+ {
|
|
|
|
|
+ $sqlPatterns = [
|
|
|
|
|
+ '/select\s.+\sfrom/i',
|
|
|
|
|
+ '/union\s+select/i',
|
|
|
|
|
+ '/insert\s+into/i',
|
|
|
|
|
+ '/update\s.+\sset/i',
|
|
|
|
|
+ '/delete\s+from/i',
|
|
|
|
|
+ '/drop\s+table/i',
|
|
|
|
|
+ '/--/',
|
|
|
|
|
+ '/\bOR\b.+\=/i',
|
|
|
|
|
+ ];
|
|
|
|
|
+ foreach (['get', 'post'] as $method) {
|
|
|
|
|
+ $params = $request->$method();
|
|
|
|
|
+ foreach ($params as $key => $value) {
|
|
|
|
|
+ if (is_string($value)) {
|
|
|
|
|
+ foreach ($sqlPatterns as $pattern) {
|
|
|
|
|
+ if (preg_match($pattern, $value)) {
|
|
|
|
|
+ $this->logSecurityViolation($request, "SQL injection pattern: $pattern in $key");
|
|
|
|
|
+ throw new \yii\web\HttpException(403, 'Access denied');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查XSS攻击
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function checkXssAttack($request)
|
|
|
|
|
+ {
|
|
|
|
|
+ $xssPatterns = [
|
|
|
|
|
+ '/<script\b[^>]*>(.*?)<\/script>/is',
|
|
|
|
|
+ '/on\w+\s*=/i',
|
|
|
|
|
+ '/javascript:/i',
|
|
|
|
|
+ '/<iframe/i',
|
|
|
|
|
+ '/<img/i',
|
|
|
|
|
+ ];
|
|
|
|
|
+ foreach (['get', 'post'] as $method) {
|
|
|
|
|
+ $params = $request->$method();
|
|
|
|
|
+ foreach ($params as $key => $value) {
|
|
|
|
|
+ if (is_string($value)) {
|
|
|
|
|
+ foreach ($xssPatterns as $pattern) {
|
|
|
|
|
+ if (preg_match($pattern, $value)) {
|
|
|
|
|
+ $this->logSecurityViolation($request, "XSS pattern: $pattern in $key");
|
|
|
|
|
+ throw new \yii\web\HttpException(403, 'Access denied');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 记录安全日志
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function logSecurityActivity($request)
|
|
|
|
|
+ {
|
|
|
|
|
+ $log = [
|
|
|
|
|
+ 'time' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'ip' => $request->userIP,
|
|
|
|
|
+ 'url' => $request->url,
|
|
|
|
|
+ 'get' => $request->get(),
|
|
|
|
|
+ 'post' => $request->post(),
|
|
|
|
|
+ 'user_agent' => $request->userAgent,
|
|
|
|
|
+ ];
|
|
|
|
|
+ file_put_contents(
|
|
|
|
|
+ Yii::getAlias('@runtime/logs/security_activity.log'),
|
|
|
|
|
+ json_encode($log, JSON_UNESCAPED_UNICODE) . "\n",
|
|
|
|
|
+ FILE_APPEND
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 记录安全违规日志
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function logSecurityViolation($request, $reason)
|
|
|
|
|
+ {
|
|
|
|
|
+ $log = [
|
|
|
|
|
+ 'time' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'ip' => $request->userIP,
|
|
|
|
|
+ 'url' => $request->url,
|
|
|
|
|
+ 'get' => $request->get(),
|
|
|
|
|
+ 'post' => $request->post(),
|
|
|
|
|
+ 'user_agent' => $request->userAgent,
|
|
|
|
|
+ 'reason' => $reason,
|
|
|
|
|
+ ];
|
|
|
|
|
+ file_put_contents(
|
|
|
|
|
+ Yii::getAlias('@runtime/logs/security_violation.log'),
|
|
|
|
|
+ json_encode($log, JSON_UNESCAPED_UNICODE) . "\n",
|
|
|
|
|
+ FILE_APPEND
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|