Support for SQL identifier composition to avoid f-strings and security linter false positives (B608) #481
Replies: 1 comment
-
|
yeah, you've read it right, there's no sql.Identifier-style helper in duckdb (checked on 1.4.4). what works today is quoting it yourself, same rule psycopg uses: wrap in double quotes and double any embedded quote. def ident(n): return '"' + n.replace('"', '""') + '"'
con.sql(f'SELECT {ident(col)} FROM {ident(tbl)}')that's injection-safe, I threw |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
While developing a QGIS data provider plugin using DuckDB (qduckdb), we build dynamic SQL queries involving:
subsetString, a QGIS API concept representing a free-form SQL filter entered by the user)What already works
DuckDB supports parameterized queries for scalar values via
execute(), similar topsycopg2:We already use this wherever possible in our plugin.
What is currently impossible
SQL identifiers (table names, column names) and arbitrary WHERE fragments cannot be passed as
?parameters. We are therefore forced to use f-strings or format:These f-strings are flagged as potential SQL injection vulnerabilities by static analysis tools (Bandit, rule B608), even though they are false positives: the values come from our own URI parsing or from the QGIS API, not from direct user input.
Wrapping
?in quotes does not work either, DuckDB treats them as string literals, not placeholders:Reference: how psycopg solves this
psycopg(v3) addresses the SQL identifier case withpsycopg.sql:DuckDB has no equivalent for this case as far as we know.
Feature request
Would it be feasible to expose a utility similar to
psycopg.sql.Identifierin DuckDB's Python API?Or is there already a recommended approach to safely compose SQL identifiers that we may have missed in the documentation?
This would allow plugin developers to write linter-clean code without resorting to
# nosecsuppression comments.Thank you in advance for your responses.
Beta Was this translation helpful? Give feedback.
All reactions