sqle
sqle copied to clipboard
MySQL V2审核规则上下文失效
版本信息(Version)
4.2511
问题描述(Describe)
审核包含创建scheam和use scheam的多条sql, 后续sql触发schema不存在规则
截图或日志(Log)
如何复现(To Reproduce)
数据源上使用MySQL V2规则,审核以下SQL语句(审核时注意不要填写数据库):
CREATE DATABASE IF NOT EXISTS test_audit_db
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE test_audit_db;
CREATE TABLE IF NOT EXISTS employee (
id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '员工ID',
emp_no VARCHAR(20) NOT NULL COMMENT '员工编号',
name VARCHAR(100) NOT NULL COMMENT '姓名',
department VARCHAR(50) COMMENT '部门',
salary DECIMAL(10,2) DEFAULT 0.00 COMMENT '薪水',
hire_date DATE NOT NULL COMMENT '入职日期',
status ENUM('active', 'inactive', 'resigned') DEFAULT 'active' COMMENT '状态',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
UNIQUE KEY uk_emp_no (emp_no)
) ENGINE=InnoDB COMMENT='员工表';
use schema 和 create table 语句误触发schema不存在规则
问题原因
解决方案
变更影响面
受影响的模块或功能
外部引用的潜在问题或风险
版本兼容性
测试建议
补充
v1 使用默认规则模板也有这个问题,不过开启建议在组合索引中将区分度高的字段靠前放这条规则刚好弥补了这个漏洞,开启这条规则后意外触发的schema不存在的规则就消失。
关键代码位置:
// IsSchemaExist check schema is exist or not.
func (c *Context) IsSchemaExist(schemaName string) (bool, error) {
if !c.hasLoadSchemas() {
if c.e == nil {
return false, nil
}
schemas, err := c.e.ShowDatabases(false)
if err != nil {
return false, err
}
c.loadSchemas(schemas)
}
lowerCaseTableNames, err := c.GetSystemVariable(SysVarLowerCaseTableNames)
if err != nil {
return false, err
}
if lowerCaseTableNames != "0" {
capitalizedSchema := make(map[string]struct{})
for name := range c.Schemas() {
capitalizedSchema[strings.ToUpper(name)] = struct{}{}
}
_, exist := capitalizedSchema[strings.ToUpper(schemaName)]
return exist, nil
}
return c.hasSchema(schemaName), nil
}
func (c *Context) setSchemasLoad() {
c.schemaHasLoad = true
}
func (c *Context) loadSchemas(schemas []string) {
if c.hasLoadSchemas() {
return
}
isLowerCaseTableName := c.IsLowerCaseTableName()
for _, schema := range schemas {
if isLowerCaseTableName {
schema = strings.ToLower(schema)
}
c.schemas[schema] = &SchemaInfo{
IsRealSchema: true,
}
}
c.setSchemasLoad()
}
func (c *Context) UpdateContext(node ast.Node) {
...
case *ast.CreateDatabaseStmt:
if c.hasLoadSchemas() {
c.addSchema(s.Name)
}
...