From c899beaebee739350bcd18cb36cd1bd3b2712f7a Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 3 Sep 2026 14:36:37 -0700 Subject: [PATCH] escape_sqlite() against column names Refs GHSA-jcvx-2fh3-pjfp Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com> --- datasette/views/table.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/datasette/views/table.py b/datasette/views/table.py index 7c814b27..51fdc950 100644 --- a/datasette/views/table.py +++ b/datasette/views/table.py @@ -1382,7 +1382,9 @@ class TableDropView(BaseView): "database": database_name, "table": table_name, "row_count": ( - await db.execute(f"select count(*) from [{table_name}]") + await db.execute( + f"select count(*) from {escape_sqlite(table_name)}" + ) ).single_value(), "message": 'Pass "confirm": true to confirm', }, @@ -2432,9 +2434,12 @@ async def _next_value_and_url( except IndexError: # sort/sort_desc column missing from SELECT - look up value by PK instead prefix_where_clause = " and ".join( - f"[{pk}] = :pk{i}" for i, pk in enumerate(pks) + f"{escape_sqlite(pk)} = :pk{i}" for i, pk in enumerate(pks) + ) + prefix_lookup_sql = ( + f"select {escape_sqlite(sort or sort_desc)} " + f"from {escape_sqlite(table_name)} where {prefix_where_clause}" ) - prefix_lookup_sql = f"select [{sort or sort_desc}] from [{table_name}] where {prefix_where_clause}" prefix = ( await db.execute( prefix_lookup_sql,