From b995e58c30380845c731ca196b3ee09ddbba7822 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 11:50:42 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20SQL=20Injection=20in=20sqliteColumnExists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced unsafe string interpolation `fmt.Sprintf("PRAGMA table_info(%s);", table)` with a parameterized query using SQLite's `pragma_table_info(?)` table-valued function. Extracted the needed columns explicitly, ensuring `"notnull"` is properly quoted. Co-authored-by: mattjoyce <278869+mattjoyce@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ internal/storage/sqlite.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 00000000..28724f2e --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-18 - Prevent SQL Injection via string interpolation in PRAGMA table_info +**Vulnerability:** Found `fmt.Sprintf("PRAGMA table_info(%s);", table)` which uses unsafe string interpolation to inject a table name directly into an SQLite schema query in `sqliteColumnExists`. +**Learning:** PRAGMA statements typically do not support parameterized arguments in many SQLite driver implementations. This led developers to incorrectly fallback to unsafe string interpolation `fmt.Sprintf` for dynamically querying schema information based on variables. +**Prevention:** Use SQLite's safe table-valued function equivalent for pragmas, specifically `pragma_table_info(?)`. This alternative syntax `SELECT ... FROM pragma_table_info(?)` safely accepts parameterized arguments, thereby eliminating SQL injection risks while retrieving schema metadata. Note that columns like `notnull` must be quoted as `"notnull"` because it is a reserved keyword in SQL. diff --git a/internal/storage/sqlite.go b/internal/storage/sqlite.go index 8c0cb1ed..1fe82e48 100644 --- a/internal/storage/sqlite.go +++ b/internal/storage/sqlite.go @@ -200,7 +200,7 @@ LIMIT 1; } func sqliteColumnExists(ctx context.Context, db *sql.DB, table, column string) (bool, error) { - cols, err := db.QueryContext(ctx, fmt.Sprintf("PRAGMA table_info(%s);", table)) + cols, err := db.QueryContext(ctx, "SELECT cid, name, type, \"notnull\", dflt_value, pk FROM pragma_table_info(?);", table) if err != nil { return false, err }