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
@@ -2090,12 +2090,110 @@ def check_mysql_sec_005(sql_clean: str, sql_upper: str, report: AuditReportV2, r
|
||||
|
||||
# ═══════════════════════════════════════════════════
|
||||
# 模块总结
|
||||
# ── SEC-006: 权限相关高危语句拦截 ──
|
||||
@register_rule(AuditRuleV2(
|
||||
code="MYSQL-SEC-006",
|
||||
name="DangerousPrivilegeStatement",
|
||||
category=RuleCategory.SECURITY,
|
||||
severity=Severity.ERROR,
|
||||
db_type="mysql",
|
||||
description="拦截 GRANT ALL / REVOKE ALL 等全局权限变更操作",
|
||||
config={"enabled": True},
|
||||
message_template="禁止执行 '{keyword}' 全局权限操作,请联系 DBA 通过权限管理流程申请",
|
||||
))
|
||||
def check_mysql_sec_006(sql_clean: str, sql_upper: str, report: AuditReportV2, rule: AuditRuleV2) -> None:
|
||||
"""全局权限语句拦截。"""
|
||||
# GRANT ALL / GRANT ALL PRIVILEGES
|
||||
if re.search(r'\bGRANT\s+ALL\b', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(keyword="GRANT ALL"),
|
||||
))
|
||||
# REVOKE ALL
|
||||
elif re.search(r'\bREVOKE\s+ALL\b', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(keyword="REVOKE ALL"),
|
||||
))
|
||||
|
||||
|
||||
# ── SEC-007: LOAD DATA / LOAD XML 拦截 ──
|
||||
@register_rule(AuditRuleV2(
|
||||
code="MYSQL-SEC-007",
|
||||
name="BlockLoadData",
|
||||
category=RuleCategory.SECURITY,
|
||||
severity=Severity.ERROR,
|
||||
db_type="mysql",
|
||||
description="禁止 LOAD DATA / LOAD XML 操作,存在安全风险且可能导入大量数据",
|
||||
config={"enabled": True},
|
||||
message_template="禁止使用 '{keyword}',该操作存在安全风险,请使用 INSERT 批量导入",
|
||||
))
|
||||
def check_mysql_sec_007(sql_clean: str, sql_upper: str, report: AuditReportV2, rule: AuditRuleV2) -> None:
|
||||
"""LOAD DATA/LOAD XML 拦截。"""
|
||||
if re.search(r'\bLOAD\s+DATA\b', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(keyword="LOAD DATA"),
|
||||
))
|
||||
elif re.search(r'\bLOAD\s+XML\b', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(keyword="LOAD XML"),
|
||||
))
|
||||
|
||||
|
||||
# ── SEC-008: SLEEP / BENCHMARK 注入拦截 ──
|
||||
@register_rule(AuditRuleV2(
|
||||
code="MYSQL-SEC-008",
|
||||
name="BlockTimeBasedInjection",
|
||||
category=RuleCategory.SECURITY,
|
||||
severity=Severity.ERROR,
|
||||
db_type="mysql",
|
||||
description="拦截 SLEEP() / BENCHMARK() 等时间盲注函数",
|
||||
config={"enabled": True},
|
||||
message_template="禁止使用 '{func}()' 函数,疑似时间盲注攻击",
|
||||
))
|
||||
def check_mysql_sec_008(sql_clean: str, sql_upper: str, report: AuditReportV2, rule: AuditRuleV2) -> None:
|
||||
"""时间盲注函数拦截。"""
|
||||
if re.search(r'\bSLEEP\s*\(', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(func="SLEEP"),
|
||||
))
|
||||
if re.search(r'\bBENCHMARK\s*\(', sql_upper):
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(func="BENCHMARK"),
|
||||
))
|
||||
|
||||
|
||||
# ── SEC-009: INTO OUTFILE / INTO DUMPFILE 拦截 ──
|
||||
@register_rule(AuditRuleV2(
|
||||
code="MYSQL-SEC-009",
|
||||
name="BlockIntoOutfile",
|
||||
category=RuleCategory.SECURITY,
|
||||
severity=Severity.ERROR,
|
||||
db_type="mysql",
|
||||
description="禁止 INTO OUTFILE / INTO DUMPFILE,防止写入 WebShell 或导出敏感数据",
|
||||
config={"enabled": True},
|
||||
message_template="禁止使用 '{keyword}',该操作可写入文件系统,存在严重安全风险",
|
||||
))
|
||||
def check_mysql_sec_009(sql_clean: str, sql_upper: str, report: AuditReportV2, rule: AuditRuleV2) -> None:
|
||||
"""INTO OUTFILE/DUMPFILE 拦截。"""
|
||||
if re.search(r'\bINTO\s+(OUT|DUMP)FILE\b', sql_upper):
|
||||
keyword = "INTO OUTFILE" if "OUTFILE" in sql_upper else "INTO DUMPFILE"
|
||||
report.findings.append(AuditFindingV2(
|
||||
rule_code=rule.code, rule_name=rule.name, level=rule.severity,
|
||||
message=rule.message_template.format(keyword=keyword),
|
||||
))
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════
|
||||
# 总计 63 条规则:
|
||||
# 总计 67 条规则:
|
||||
# - DDL 规则: 36 条 (MYSQL-DDL-001 ~ MYSQL-DDL-036)
|
||||
# - DML 规则: 9 条 (MYSQL-DML-001 ~ MYSQL-DML-009)
|
||||
# - Online-DDL 规则: 3 条 (MYSQL-OSC-001 ~ MYSQL-OSC-003)
|
||||
# - 命名规则: 5 条 (MYSQL-NAM-001 ~ MYSQL-NAM-005)
|
||||
# - 性能规则: 5 条 (MYSQL-PERF-001 ~ MYSQL-PERF-005)
|
||||
# - 安全规则: 5 条 (MYSQL-SEC-001 ~ MYSQL-SEC-005)
|
||||
# - 安全规则: 9 条 (MYSQL-SEC-001 ~ MYSQL-SEC-009)
|
||||
# ═══════════════════════════════════════════════════
|
||||
Reference in new issue
Block a user