sqle icon indicating copy to clipboard operation
sqle copied to clipboard

MySQL V2审核规则上下文失效

Open iwanghc opened this issue 3 weeks ago • 1 comments

版本信息(Version)

4.2511

问题描述(Describe)

审核包含创建scheam和use scheam的多条sql, 后续sql触发schema不存在规则

截图或日志(Log)

Image

Image

Image

Image

如何复现(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不存在规则

问题原因

解决方案

变更影响面

受影响的模块或功能

外部引用的潜在问题或风险

版本兼容性

测试建议

iwanghc avatar Dec 05 '25 08:12 iwanghc

补充

v1 使用默认规则模板也有这个问题,不过开启建议在组合索引中将区分度高的字段靠前放这条规则刚好弥补了这个漏洞,开启这条规则后意外触发的schema不存在的规则就消失。 关键代码位置: Image

// 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)
		}
...

iwanghc avatar Dec 08 '25 06:12 iwanghc