补充动态SQL标识符安全说明
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-22 03:58:22 +08:00
parent d5ae1a30e1
commit 3f07dc8e8e
2 changed files with 5 additions and 0 deletions

View File

@ -190,6 +190,7 @@ func copyPortableTables(ctx context.Context, source *sql.Conn, target *sql.DB, p
} }
// 只有绑定序列的主键需要推进;日志等文本主键不能参与数值聚合。 // 只有绑定序列的主键需要推进;日志等文本主键不能参与数值聚合。
if sequence.Valid { if sequence.Valid {
// #nosec G202 -- 表名来自数据库元数据,并通过标识符引用;数据值仍使用参数。
query := "SELECT setval($1::regclass, COALESCE(MAX(id), 1), MAX(id) IS NOT NULL) FROM " + quoted query := "SELECT setval($1::regclass, COALESCE(MAX(id), 1), MAX(id) IS NOT NULL) FROM " + quoted
if _, err := transaction.ExecContext(ctx, query, sequence.String); err != nil { if _, err := transaction.ExecContext(ctx, query, sequence.String); err != nil {
return ErrSQLDataVerification return ErrSQLDataVerification
@ -235,6 +236,7 @@ func synchronizeSequences(ctx context.Context, transaction *sql.Tx, plan Plan, s
return ErrSQLDataVerification return ErrSQLDataVerification
} }
case config.DatabaseTypePostgreSQL: case config.DatabaseTypePostgreSQL:
// #nosec G202 -- 序列名称来自数据库元数据,并通过 PostgreSQL 标识符引用;数值使用参数。
query := "SELECT setval(pg_get_serial_sequence($1, 'id'), GREATEST(COALESCE(MAX(id), 0), $2), true) FROM " + quotePostgreSQLIdentifier(sequence.Name) query := "SELECT setval(pg_get_serial_sequence($1, 'id'), GREATEST(COALESCE(MAX(id), 0), $2), true) FROM " + quotePostgreSQLIdentifier(sequence.Name)
if _, err := transaction.ExecContext(ctx, query, sequence.Name, sequence.Seq); err != nil { if _, err := transaction.ExecContext(ctx, query, sequence.Name, sequence.Seq); err != nil {
return ErrSQLDataVerification return ErrSQLDataVerification

View File

@ -236,6 +236,7 @@ func (c *SQLCopier) copyMySQL(ctx context.Context, sourceDB, adminDB *sql.DB, so
} }
}() }()
// #nosec G202 -- 数据库名称来自已校验配置,并通过 MySQL 标识符引用。
rows, err := sourceDB.QueryContext(ctx, "SHOW FULL TABLES FROM "+quoteMySQLIdentifier(sourceName)) rows, err := sourceDB.QueryContext(ctx, "SHOW FULL TABLES FROM "+quoteMySQLIdentifier(sourceName))
if err != nil { if err != nil {
return fmt.Errorf("list mysql tables: %w", err) return fmt.Errorf("list mysql tables: %w", err)
@ -275,6 +276,7 @@ func (c *SQLCopier) copyMySQL(ctx context.Context, sourceDB, adminDB *sql.DB, so
} }
sourceTable := quoteMySQLIdentifier(sourceName) + "." + quoteMySQLIdentifier(tableName) sourceTable := quoteMySQLIdentifier(sourceName) + "." + quoteMySQLIdentifier(tableName)
targetTable := quoteMySQLIdentifier(targetName) + "." + quoteMySQLIdentifier(tableName) targetTable := quoteMySQLIdentifier(targetName) + "." + quoteMySQLIdentifier(tableName)
// #nosec G202 -- 源表和目标表均来自数据库元数据并通过 MySQL 标识符引用。
if _, err := adminDB.ExecContext(ctx, "INSERT INTO "+targetTable+" SELECT * FROM "+sourceTable); err != nil { if _, err := adminDB.ExecContext(ctx, "INSERT INTO "+targetTable+" SELECT * FROM "+sourceTable); err != nil {
return fmt.Errorf("copy mysql table data: %w", err) return fmt.Errorf("copy mysql table data: %w", err)
} }
@ -362,6 +364,7 @@ func (c *SQLCopier) copyMySQLForeignKeys(ctx context.Context, database *sql.DB,
} }
columns := quoteMySQLIdentifiers(foreignKey.columns) columns := quoteMySQLIdentifiers(foreignKey.columns)
referencedColumns := quoteMySQLIdentifiers(foreignKey.referencedColumns) referencedColumns := quoteMySQLIdentifiers(foreignKey.referencedColumns)
// #nosec G202 -- 外键标识符统一引用,更新和删除规则已通过白名单校验。
query := "ALTER TABLE " + quoteMySQLIdentifier(targetName) + "." + quoteMySQLIdentifier(foreignKey.tableName) + " ADD CONSTRAINT " + quoteMySQLIdentifier(foreignKey.constraintName) + " FOREIGN KEY (" + strings.Join(columns, ", ") + ") REFERENCES " + quoteMySQLIdentifier(referencedSchema) + "." + quoteMySQLIdentifier(foreignKey.referencedTable) + " (" + strings.Join(referencedColumns, ", ") + ") ON UPDATE " + foreignKey.updateRule + " ON DELETE " + foreignKey.deleteRule query := "ALTER TABLE " + quoteMySQLIdentifier(targetName) + "." + quoteMySQLIdentifier(foreignKey.tableName) + " ADD CONSTRAINT " + quoteMySQLIdentifier(foreignKey.constraintName) + " FOREIGN KEY (" + strings.Join(columns, ", ") + ") REFERENCES " + quoteMySQLIdentifier(referencedSchema) + "." + quoteMySQLIdentifier(foreignKey.referencedTable) + " (" + strings.Join(referencedColumns, ", ") + ") ON UPDATE " + foreignKey.updateRule + " ON DELETE " + foreignKey.deleteRule
if _, err := database.ExecContext(ctx, query); err != nil { if _, err := database.ExecContext(ctx, query); err != nil {
return fmt.Errorf("copy mysql foreign key: %w", err) return fmt.Errorf("copy mysql foreign key: %w", err)