Skip to content

Escape closing brackets in T-SQL identifier quoting#400

Open
sdebruyn wants to merge 1 commit into
microsoft:mainfrom
sdebruyn:up-07
Open

Escape closing brackets in T-SQL identifier quoting#400
sdebruyn wants to merge 1 commit into
microsoft:mainfrom
sdebruyn:up-07

Conversation

@sdebruyn
Copy link
Copy Markdown
Collaborator

Fixes #399.

FabricAdapter.quote(), FabricColumn.quoted, FabricRelation.quoted, and five Jinja macro sites all compose bracket-quoted T-SQL identifiers without escaping ]. Any identifier containing ] produces invalid T-SQL, and a crafted identifier of the form foo];<sql>-- lets a name terminate the bracket and inject arbitrary T-SQL into whatever statement the macro is composing. The dbt-fabric attack surface is small (identifiers are usually static), but projects that derive names from external systems are exposed, and silent breakage on reserved-word columns containing ] is a real bug regardless.

Changes

Doubling ] to ]] inside the brackets is the standard T-SQL escape (Delimited Identifiers). Applied at every bracket-quoting site:

  • FabricAdapter.quote()identifier.replace("]", "]]") before the format.
  • FabricColumn.quoted — same on self.column.
  • FabricRelation.quoted() — same on identifier.
  • fabric__alter_column_type (columns.sql) — both the CAST source and the alias.
  • fabric__alter_relation_add_remove_columns (columns.sql) — add and drop column branches.
  • fabric__create_table_as (create_table_as.sql) — the listColumns block used for contract.enforced models.
  • fabric__create_columns (snapshot helpers.sql) — column addition during snapshot column expansion.

The Jinja escape uses the standard | replace(']', ']]') filter inside the existing [ ... ] wrapper.

Out of scope

This PR only adds the missing escape. Two related quoting inconsistencies were noticed while writing the patch but kept out to keep the diff reviewable:

  • fabric__alter_column_type's metadata-query branch composes column names with double quotes ('"' + ... + '"') while the rest of the file uses brackets.
  • fabric__get_use_database_sql currently strips [/]/" from the database name rather than escaping them. That is safe against injection but silently rewrites identifiers that legitimately contain those characters.

Happy to follow up on either in separate PRs if useful.

Bracket-quoted T-SQL identifiers require a literal ] to be doubled
(]]) to avoid prematurely closing the bracket. Without escaping, any
identifier containing ] either generates invalid T-SQL (silent
breakage for reserved-word column names that happen to contain ])
or, more importantly, lets a crafted identifier terminate the
bracket and inject arbitrary T-SQL.

Apply the escape to every bracket-quoting site:

- FabricAdapter.quote()
- FabricColumn.quoted
- FabricRelation.quoted
- fabric__alter_column_type (columns.sql)
- fabric__alter_relation_add_remove_columns (columns.sql)
- fabric__create_table_as listColumns block (create_table_as.sql)
- fabric__create_columns (snapshots/helpers.sql)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FabricAdapter.quote() does not escape closing brackets — invalid SQL and identifier-injection risk

1 participant