Summary
PR #471 relocates the SQL identifier quoter to sqlspec.utils.text.quote_identifier (it had been miscoped as sqlspec.migrations.utils.quote_migration_identifier). Today only the migration session-schema hooks use it. There may be other code paths that interpolate identifier-shaped values into SQL strings (DDL identifiers, SET commands, dynamically constructed table/column references in adapter-specific code) without the equivalent quoting.
Scope
- Grep every adapter and migration code path for f-string /
%-format / format() interpolation of column/table/schema names into SQL.
- Replace each with
quote_identifier(...).
- Add a lint rule (ruff custom or codespell-style) or a doctest pattern to keep new code on the helper.
Suspects to audit (not exhaustive)
sqlspec/adapters/oracledb/migrations.py — interpolates version_table_schema directly into a SQL fragment.
sqlspec/adapters/mssql_python/migrations.py — _split_schema_table + raw concatenation in CREATE/ALTER text.
- Any place a
version_table value reaches a DDL statement without going through a builder.
This is a hardening pass; nothing here is a confirmed CVE-shaped bug, but identifier-interpolation surfaces are exactly where SQL-injection-via-config issues hide.
Summary
PR #471 relocates the SQL identifier quoter to
sqlspec.utils.text.quote_identifier(it had been miscoped assqlspec.migrations.utils.quote_migration_identifier). Today only the migration session-schema hooks use it. There may be other code paths that interpolate identifier-shaped values into SQL strings (DDL identifiers,SETcommands, dynamically constructed table/column references in adapter-specific code) without the equivalent quoting.Scope
%-format /format()interpolation of column/table/schema names into SQL.quote_identifier(...).Suspects to audit (not exhaustive)
sqlspec/adapters/oracledb/migrations.py— interpolatesversion_table_schemadirectly into a SQL fragment.sqlspec/adapters/mssql_python/migrations.py—_split_schema_table+ raw concatenation in CREATE/ALTER text.version_tablevalue reaches a DDL statement without going through a builder.This is a hardening pass; nothing here is a confirmed CVE-shaped bug, but identifier-interpolation surfaces are exactly where SQL-injection-via-config issues hide.