Skip to content

plugins/destination/duckdb + sqlite: SQL injection in PRAGMA table_info queries #23171

Description

@praneshnikhar

DuckDB + SQLite: SQL injection in PRAGMA table_info queries

DuckDB

File: plugins/destination/duckdb/client/migrate.go:13

Problem: PRAGMA table_info('%s') is called with fmt.Sprintf and the table name is interpolated directly. If the table name contains single quotes, an attacker can break out of the string literal.

Current code:

const (
    sqlTableInfo = "PRAGMA table_info('%s');"
)
// used as:
rows, err := c.db.Query(fmt.Sprintf(sqlTableInfo, tableName))

Fix: Use the parameterized form:

const (
    sqlTableInfo = "SELECT * FROM pragma_table_info($1)"
)
// used as:
rows, err := c.db.Query(sqlTableInfo, tableName)

SQLite

File: plugins/destination/sqlite/client/migrate.go:17

Problem: Same pattern — PRAGMA table_info('%s') with string formatting. SQLite doesn't support parameterized PRAGMA queries, so the fix escapes single quotes by doubling them.

Current code:

const (
    sqlTableInfo = "PRAGMA table_info('%s');"
)

Fix: Escape single quotes with strings.ReplaceAll(name, "'", "''"):

rows, err := c.db.Query(fmt.Sprintf(sqlTableInfo, sanitizeSQLiteIdentifier(tableName)))

Reproduction

Use a source plugin that syncs to a table with a single quote in the name (e.g., foo'bar). The query breaks:

  • DuckDB: PRAGMA table_info('foo'bar') — syntax error or injection
  • SQLite: same issue

With a malicious table name like '; DROP TABLE duckdb_constraints; --, arbitrary SQL can be injected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions