ShuanghongS 5 달 전
부모
커밋
6a7263b0dc
3개의 변경된 파일85개의 추가작업 그리고 31개의 파일을 삭제
  1. 29 8
      service/robot.class.php
  2. 18 23
      service/tools.class.php
  3. 38 0
      utils/common.class.php

+ 29 - 8
service/robot.class.php

@@ -886,6 +886,22 @@ class robot{
         }
         $request_content = common::check_input(json_encode($response['data']));
         $ai_response_content = common::check_input(json_encode($response['full_response']));
+
+        //提前记录AI 返回,如果sql异常掉了的话,可以查找原因
+        $updateSql = "update public.kln_robot_chat_log set answer_duration = '$response_duration',answer_template='$answer_template',
+            answer_type = case when COALESCE(answer_type,'') = 'Suspend' then 'Suspend' else '$answer_type' end,
+            request_content='$request_content',
+            input_token='$input_token',ai_response_content='$ai_response_content',
+            output_token='$output_token',response_time=now(),response_duration='$response_duration'
+        where serial_no = '$serial_no'";
+
+        $updateRs = common::excuteUpdateSql($updateSql);
+        if (!$updateRs) {
+            $data = array("type"=>"markdown","data" => "AI Chat Response Save Error");
+            common::echo_json_encode(200,$data);
+            exit();
+        }
+
         $message = json_decode(common::getChatAimessage($response['message']),true);
         if($message["can_query"] == "true" && !empty($message["sql"])){
             $reference = $message["reference"];
@@ -895,15 +911,24 @@ class robot{
             $sqlArr = explode(";", $sql);
             //给所有sql 拼接用户权限
             $sqlWhere = '  ' . common::searchExtendHand_KLN("ocean", $_SESSION["ONLINE_USER"]);
-            //先不考虑总数,处理有难度
+
             foreach($sqlArr as $_sql){
                 if(empty($_sql)){
                     continue;
                 }
+                //首先检查sql 是否有非法的字符和不规范查询
+                $safe = common::checkSafeSql($_sql);
+                if(!$safe){
+                    $reference = "The answer is incorrect. It has been filtered.";
+                    break;
+                }
+
                 //根据public.kln_ocean 和 WHERE 的位置关系,带入权限
                 $new_sql = utils::modifyString($_sql,$sqlWhere);
+                
                 //处理limit 超过10 先限制10
                 //$new_sql = utils::processLimitClause($new_sql);
+                
                 //$rs = common::excuteListSql($new_sql);
                 $rs =  $mapdb->GetAll($new_sql) or ( (!$mapdb->ErrorMsg()) or error_log(common::dbLog($mapdb, $new_sql), 0));
                 $reference = utils::replacementsMultiline($rs,$reference,$new_sql);
@@ -921,13 +946,9 @@ class robot{
             }
         }
 
-        //update 更新
-        $updateSql = "update public.kln_robot_chat_log set answer_duration = '$response_duration',answer_template='$answer_template',answer = '".common::check_input($answer)."',
-            answer_type = case when COALESCE(answer_type,'') = 'Suspend' then 'Suspend' else '$answer_type' end,
-            request_content='$request_content',
-            input_token='$input_token',ai_response_content='$ai_response_content',
-            output_token='$output_token',response_time=now(),response_duration='$response_duration'
-        where serial_no = '$serial_no'";
+        //update 更新 answer
+        $updateSql = "update public.kln_robot_chat_log set answer = '".common::check_input($answer)."'
+            where serial_no = '$serial_no'";
 
         $updateRs = common::excuteUpdateSql($updateSql);
         if (!$updateRs) {

+ 18 - 23
service/tools.class.php

@@ -751,7 +751,7 @@ class tools {
                     else '' 
                     end  as insert_date_format  
                 from  public.kln_notifiation_info ni
-                where ni.insert_date > NOW() - INTERVAL '1 year' 
+                where ni.insert_date > NOW() - INTERVAL '3 months' 
                     and ni.notifications_method = 'true' and ni.is_send_message is null
                     and lower(ni.user_login) = '".strtolower(_getLoginName())."'
                     and ((ni.frequency_type = 'Daily'  
@@ -771,7 +771,7 @@ class tools {
             union all
                 select ni.notifiation_type, '' as insert_date_format  
                     from  public.kln_notifiation_info ni
-                    where ni.insert_date > NOW() - INTERVAL '1 year' 
+                    where ni.insert_date > NOW() - INTERVAL '3 months' 
                         and lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
                         and ni.notifications_method = 'true' and ni.is_send_message is null
                         and frequency_type = 'Instant'  
@@ -875,7 +875,7 @@ class tools {
                     else '' 
                     end  as insert_date_format  
                 from  public.kln_notifiation_info ni
-                where ni.insert_date > NOW() - INTERVAL '1 year' 
+                where ni.insert_date > NOW() - INTERVAL '3 months' 
                     and ni.notifications_method = 'true' and ni.is_send_message is null
                     and lower(ni.user_login) = '".strtolower(_getLoginName())."'
                     and ((ni.frequency_type = 'Daily'  
@@ -895,7 +895,7 @@ class tools {
             union all
                 select ni.notifiation_type, '' as insert_date_format  
                     from  public.kln_notifiation_info ni
-                    where ni.insert_date > NOW() - INTERVAL '1 year' 
+                    where ni.insert_date > NOW() - INTERVAL '3 months' 
                         and lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
                         and ni.notifications_method = 'true' and ni.is_send_message is null
                         and frequency_type = 'Instant'  
@@ -1663,7 +1663,7 @@ class tools {
                             where oo.serial_no = ni.serial_no limit 1) ccc on true
                         left join LATERAL (select COALESCE(ke.default_time_zone,'UTC-08') as default_time_zone from public.kln_user_extend ke where lower(ke.user_login) = lower(ni.user_login) limit 1) ddd on true    
                 where lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
-                        and ni.insert_date > NOW() - INTERVAL '1 year' 
+                        and ni.insert_date > NOW() - INTERVAL '3 months' 
                         and lower(ni.notifiation_type) in ($more_param)
                     ".$sql_where." and ni.notifications_method = true order by ni.insert_date desc) aa $aa_where";
         error_log($sql);
@@ -1785,15 +1785,12 @@ class tools {
 
         $cp = common::check_input($_REQUEST['cp']); //current_page
         $ps = common::check_input($_REQUEST['ps']); //ps
-        if (empty($ps)){
-            $ps = 20;
-        }
-        if (empty($cp)){
-            $cp = 1;
+        if (empty($ps) || empty($cp)){
+            $limit_param = " ";
+        } else {
+            $limit_param = " limit " . $ps . " offset " . ($cp - 1) * $ps;
         }
-        //$limit_param = " limit " . $ps . " offset " . ($cp - 1) * $ps;
-        $limit_param = " ";
-
+        
         $sql = "WITH base_data AS (
                     SELECT 
                         id,
@@ -1817,7 +1814,7 @@ class tools {
                         date_change_name
                     FROM public.kln_notifiation_info ni
                     WHERE lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
-                    AND ni.insert_date > NOW() - INTERVAL '1 year' 
+                    AND ni.insert_date > NOW() - INTERVAL '3 months' 
                     and lower(ni.notifiation_type) in ($more_param)
                     AND frequency_type IN ('Daily', 'Weekly')
                     ".$sql_where." and ni.notifications_method = true
@@ -1825,7 +1822,7 @@ class tools {
                 base_instant_data AS (
                     SELECT id,insert_date FROM public.kln_notifiation_info ni
                     WHERE  lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
-                    AND ni.insert_date > NOW() - INTERVAL '1 year'
+                    AND ni.insert_date > NOW() - INTERVAL '3 months'
                     and lower(ni.notifiation_type) in ($more_param)
                     AND frequency_type  = 'Instant'
                     ".$sql_where." and ni.notifications_method = true
@@ -2021,14 +2018,12 @@ class tools {
 
         $cp = common::check_input($_REQUEST['cp']); //current_page
         $ps = common::check_input($_REQUEST['ps']); //ps
-        if (empty($ps)){
-            $ps = 20;
-        }
-        if (empty($cp)){
-            $cp = 1;
+
+        if (empty($ps) || empty($cp)){
+            $limit_param = " ";
+        } else {
+            $limit_param = " limit " . $ps . " offset " . ($cp - 1) * $ps;
         }
-        //$limit_param = " limit " . $ps . " offset " . ($cp - 1) * $ps;
-        $limit_param = " ";
 
         $sql = "select *
                  from  (select ni.*,
@@ -2089,7 +2084,7 @@ class tools {
                         else '' 
                     end  as insert_date_format) eee on true      
                 where lower(ni.user_login) in ('".strtolower(_getLoginName())."','all_user')
-                        and ni.insert_date > NOW() - INTERVAL '1 year' 
+                        and ni.insert_date > NOW() - INTERVAL '3 months' 
                         and lower(ni.notifiation_type) in ($more_param)
                     ".$sql_where." and ni.notifications_method = true order by ni.insert_date desc) aa 
                 WHERE rn = 1 ORDER BY insert_date DESC " .$limit_param;

+ 38 - 0
utils/common.class.php

@@ -2507,6 +2507,44 @@ class common {
         return $data;
     }
 
+    public static function checkSafeSql($input) { 
+        $data = true;       
+        // 定义危险 SQL 关键字列表
+        $dangerousKeywords = [
+           'INSERT', 'UPDATE', 'DELETE', 'DROP', 'ALTER', 'CREATE', 
+           'UNION', 'EXEC', 'EXECUTE', 'TRUNCATE', 'GRANT', 'REVOKE', 
+           'WAITFOR', 'DELAY', 'PG_SLEEP'
+        ];
+       
+        // 检查是否包含危险关键字(不区分大小写)
+        foreach ($dangerousKeywords as $keyword) {
+            if (stripos($input, $keyword) !== false) {
+                $data = false;
+            }
+        }
+       
+        // 可选:进一步确认是否为 SELECT 查询
+        if (!preg_match('/^\s*SELECT\b/i', trim($input))) {
+           $data = false; // 不是以 SELECT 开头
+        }
+
+        // 转为小写统一处理
+        $sqlLower = strtolower($input);
+        // 查找 'from' 出现的位置
+        $fromPos = stripos($sqlLower, 'from');
+        if ($fromPos === false) {
+            return false; // 没有 from,不可能有 where,直接返回 false
+        }
+
+        // 从 from 之后的部分中查找 where
+        $afterFrom = substr($sqlLower, $fromPos + 4); // +4 是跳过 'from'
+        if (stripos($afterFrom, 'WHERE') === false){
+            $data = false; // 简单的判断是否带条件查询
+        }
+
+        return $data;
+    }
+
     //预加载写法
     public static function excuteObjectPrepareSql($sql,$param) {
         if (empty($sql))