fix: 审核引擎优化 + 执行结果结构化展示
后端审核规则修复: - Redis SEC-001: SET/DEL等常规命令不再误报AUTH要求,改为仅对管理级命令WARNING - Redis SEC-003: 降级为INFO,排除已由CMD-001拦截的FLUSHDB/FLUSHALL - Redis key提取: 排除CONFIG/ACL等管理命令,不再把子命令参数误认为key名 - MySQL SEC-006: 新增GRANT ALL/REVOKE ALL全局权限拦截 - MySQL SEC-007: 新增LOAD DATA/LOAD XML拦截 - MySQL SEC-008: 新增SLEEP()/BENCHMARK()时间盲注拦截 - MySQL SEC-009: 新增INTO OUTFILE/DUMPFILE文件写入拦截 前端执行结果结构化: - TicketDetailPage执行结果从原始JSON改为结构化展示 - 解析JSON展示: 状态徽章+影响行数+耗时+验证状态 - Errors/Warnings逐条渲染: 红色错误框+黄色警告框+具体消息 - 删除废弃的executeStats/renderExecuteStats 其他: 审核规则6分组/慢查询移除/查询数据重命名/AuditLogs修复 测试: 1040 passed, TSC零错误
This commit is contained in:
1 parent
9f56e866f2
commit
4ac2528f8e
19 files changed
+1202
-325
No files matched your search
@@ -5,6 +5,7 @@ Replaces mock aiomysql calls with actual driver connections.
|
||||
"""
|
||||
import asyncio
|
||||
import time
|
||||
import asyncio
|
||||
import sqlite3
|
||||
from typing import Optional, List, Dict, Any, Tuple
|
||||
|
||||
@@ -61,12 +62,68 @@ class DBConnector:
|
||||
return await DBConnector._test_postgres(instance, start)
|
||||
elif instance.db_type == "sqlite":
|
||||
return await DBConnector._test_sqlite(instance, start)
|
||||
elif instance.db_type == "redis":
|
||||
return await DBConnector._test_redis(instance, start)
|
||||
elif instance.db_type == "mongodb":
|
||||
return await DBConnector._test_mongodb(instance, start)
|
||||
else:
|
||||
return ConnectionResult(False, f"暂不支持 {instance.db_type} 类型数据源")
|
||||
except Exception as e:
|
||||
elapsed = int((time.time() - start) * 1000)
|
||||
return ConnectionResult(False, f"连接失败: {str(e)}", latency_ms=elapsed)
|
||||
|
||||
|
||||
@staticmethod
|
||||
async def _test_redis(instance: 'Instance', start: float) -> ConnectionResult:
|
||||
"""Test Redis connectivity using synchronous redis client in thread."""
|
||||
try:
|
||||
import redis as redis_lib
|
||||
|
||||
def _connect():
|
||||
client = redis_lib.Redis(
|
||||
host=instance.host,
|
||||
port=instance.port,
|
||||
password=instance.password if instance.password and instance.password != "default" else None,
|
||||
db=0,
|
||||
socket_connect_timeout=5,
|
||||
socket_timeout=5,
|
||||
)
|
||||
info = client.info("server")
|
||||
version = info.get("redis_version", "unknown")
|
||||
client.close()
|
||||
return version
|
||||
|
||||
version = await asyncio.to_thread(_connect)
|
||||
elapsed = int((time.time() - start) * 1000)
|
||||
return ConnectionResult(True, f"Redis {version} 连接成功", version=version, latency_ms=elapsed)
|
||||
except Exception as e:
|
||||
elapsed = int((time.time() - start) * 1000)
|
||||
return ConnectionResult(False, f"Redis 连接失败: {str(e)}", latency_ms=elapsed)
|
||||
|
||||
@staticmethod
|
||||
async def _test_mongodb(instance: 'Instance', start: float) -> ConnectionResult:
|
||||
"""Test MongoDB connectivity using pymongo in thread."""
|
||||
try:
|
||||
from pymongo import MongoClient
|
||||
|
||||
def _connect():
|
||||
if instance.username and instance.username != "default":
|
||||
uri = f"mongodb://{instance.username}:{instance.password}@{instance.host}:{instance.port}/"
|
||||
else:
|
||||
uri = f"mongodb://{instance.host}:{instance.port}/"
|
||||
client = MongoClient(uri, serverSelectionTimeoutMS=5000, connectTimeoutMS=5000)
|
||||
info = client.server_info()
|
||||
version = info.get("version", "unknown")
|
||||
client.close()
|
||||
return version
|
||||
|
||||
version = await asyncio.to_thread(_connect)
|
||||
elapsed = int((time.time() - start) * 1000)
|
||||
return ConnectionResult(True, f"MongoDB {version} 连接成功", version=version, latency_ms=elapsed)
|
||||
except Exception as e:
|
||||
elapsed = int((time.time() - start) * 1000)
|
||||
return ConnectionResult(False, f"MongoDB 连接失败: {str(e)}", latency_ms=elapsed)
|
||||
|
||||
@staticmethod
|
||||
async def execute_query(
|
||||
instance: Instance, database: Optional[str], sql: str, user_id: int
|
||||
|
||||
Reference in new issue
Block a user