Commit graph

3,448 commits

Author SHA1 Message Date
Simon Willison
628cec8f0c Block framing of stored-query mutation forms 2026-09-09 08:39:03 -07:00
Simon Willison
506c4bb522 Match table permission identities using SQLite case semantics 2026-09-09 08:39:03 -07:00
Simon Willison
e429bd2efa Reuse trusted magic parameter bindings for CSV exports 2026-09-09 08:39:03 -07:00
Alex Garcia
c6ba7b3298 Refuse API token creation from restricted actors 2026-09-09 08:38:40 -07:00
Simon Willison
ac2a9a43a5 Add a default execution time limit to writes 2026-09-08 21:17:03 -07:00
Simon Willison
9d3d741620 Require view permission before using row labels in flash messages 2026-09-08 21:16:36 -07:00
Simon Willison
ceef351622 Protect personalized dynamic responses from shared caching 2026-09-08 21:16:36 -07:00
Simon Willison
7e6039b8df Normalize URL column schemes consistently 2026-09-08 21:16:35 -07:00
Simon Willison
d43a04eb54 Authorize row resources before resolving primary keys 2026-09-08 21:16:35 -07:00
Simon Willison
8b10f58e1b Reject untrusted table-valued PRAGMA reads 2026-09-08 21:16:35 -07:00
Simon Willison
4b8f3b484d Keep private row and table responses out of shared caches 2026-09-08 21:16:35 -07:00
Simon Willison
1be4df77ac Reject invalid token expiry input 2026-09-08 21:16:35 -07:00
Simon Willison
6aa58bf4e5 Authorize configured full-text search targets 2026-09-08 21:16:35 -07:00
Simon Willison
22c601b3d0 Redact configuration keys case-insensitively 2026-09-08 21:16:35 -07:00
Simon Willison
e949ae46de Use unshadowable table classification 2026-09-08 21:16:35 -07:00
Simon Willison
a365903d56 Require view permission before returning written rows 2026-09-08 21:16:35 -07:00
Simon Willison
4c56ce2103 Escape identifiers in upsert row readback 2026-09-08 21:16:35 -07:00
Simon Willison
158c88f259 Escape primary-key cell values in row pages 2026-09-08 21:16:34 -07:00
Simon Willison
35232b5c37 Escape primary-key identifiers in row queries 2026-09-08 21:16:34 -07:00
Simon Willison
c01e95f3bd Filter foreign-key helper targets by view permission 2026-09-08 21:14:10 -07:00
Simon Willison
bf348a22fc Escape LIKE metacharacters in FTS detection 2026-09-08 21:12:23 -07:00
Simon Willison
59618371e9 Validate URL before rendering column links 2026-09-08 21:11:44 -07:00
Simon Willison
5de0c1724e Viewing derived table requires permission for both table and its source
Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 18:09:23 -07:00
Simon Willison
d06737b6f4 Fix CREATE VIEW analysis on Python 3.10 2026-09-08 10:49:52 -07:00
Simon Willison
6473a7ecb0 Clearly document relationship between execute-sql and facets
Refs GHSA-5fff-xcm9-q6vh

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:49:52 -07:00
Simon Willison
f6d0f9bd38 detect_fts() now uses parameterized SQL
Refs GHSA-jcvx-2fh3-pjfp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:20 -07:00
Simon Willison
c899beaebe escape_sqlite() against column names
Refs GHSA-jcvx-2fh3-pjfp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:20 -07:00
Simon Willison
3ae092896d Only allow /db/name/-/schema against tables and views
Refs GHSA-926p-cw2f-643h

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:20 -07:00
Simon Willison
5d9a74f370 Check view-table as part of /-/schema and /db/-/schema
Refs GHSA-926p-cw2f-643h

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
01bf476d51 Require view-instance permission for /-/allowed
Refs GHSA-hp2x-vx2r-6vxg

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
4904249025 Use .textContent for column names in column chooser
Refs GHSA-hp2x-vx2r-6vxg

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
435e55ff0a Remove JSON syntax highlighting
Refs GHSA-hp2x-vx2r-6vxg

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
f8e8e65af7 actor cookie respects expire_after
Refs GHSA-53fc-rhfg-h7qp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
577aeb73f0 Disallow ?_through= if user lacks view-table permission
Refs GHSA-53fc-rhfg-h7qp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
c280c47424 POST /db/-/create checks table-level insert/update/alter permissions
Refs GHSA-53fc-rhfg-h7qp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
4d0a2f2e84 execute-write: Check view-table for every table in a CREATE VIEW
Refs GHSA-53fc-rhfg-h7qp

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Simon Willison
c7944fc454 Skip deploy if environment variables are missing 2026-09-08 10:48:19 -07:00
Simon Willison
bdaa8cc76c Disable extension loading once --load-extension extensions are loaded
Refs GHSA-2mvv-ffvc-q5p6

Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com>
2026-09-08 10:48:19 -07:00
Zain Dana Harper
7403ae68bb Give each non-blocking write a distinct task id, refs #2860, #2859
execute_write_fn(fn, block=False) is documented to return "a UUID representing
the queued task". Two things stopped that being true.

_send_to_write_thread() derived the id from uuid.uuid5(NAMESPACE_DNS,
"datasette.io"), which is deterministic, so every non-blocking write in every
database in every process returned 3f143baa-4e3d-5842-a36f-4fa2f683b72f. A
constant cannot identify a particular task. Now uuid4(). Refs #2860.

With num_sql_threads=0 there is no write thread, so execute_write_fn took the
synchronous branch and `result` was the write function's return value, normally
None. The block=False path then unpacked it unconditionally and raised
TypeError: cannot unpack non-iterable NoneType object. The non-threaded branch
now returns the same (task_id, reply_future) shape, with the future already
resolved because the write has finished, so both modes share one code path.
Refs #2859.

test_execute_write_fn_block_false only asserted isinstance(task_id, uuid.UUID),
which a constant satisfies. The new test is parametrized over threaded and
non-threaded and asserts two calls return different ids, so either regression
fails it.
2026-09-08 10:03:52 -07:00
Simon Willison
bdc9731740
check-latest: true, add 3.15 to test matrix, to test RCs (#2895)
See https://simonwillison.net/2026/Sep/1/python-315-rc-2/
2026-09-01 13:37:15 -07:00
Alex Garcia
3e018bb1b5
Run startup via ASGI lifespan instead of waiting for the first request (#2887)
* Run startup via ASGI lifespan instead of waiting for the first request
* Ensure immutable table counts still precompute when startup ran first
2026-09-01 09:39:25 -07:00
Alex Garcia
e78b8a2e6a
Run datasette serve startup and uvicorn on a single event loop (#2886)
* Run datasette serve startup and uvicorn on a single event loop
* Move the serve-subprocess test plumbing into a conftest fixture
* Fix datasette-litestream URL and trim marker-task test comments
* Explain why serve_with_plugins needs a subprocess and plugin files
* Apply ruff 0.16 and black fixes
* Tweaked some comments
2026-09-01 09:32:37 -07:00
Simon Willison
0337fba234
disable_fts() before dropping table
Closes #2874
2026-08-10 15:03:29 -07:00
Simon Willison
12b25affb5 Release 1.0a38 1.0a38
Refs #2868
2026-08-06 11:20:25 -07:00
Simon Willison
eb6c2b96b9 Fix for SQL injection issue in table filters, refs #2868 2026-08-06 11:19:50 -07:00
Simon Willison
e889403d3b
Upgrade to ruff>=0.16.0 (#2857)
* ruff>=0.16.0

See https://astral.sh/blog/ruff-v0.16.0

* uv run ruff check . --fix --unsafe-fixes

* Ruff fixes by Claude Code Opus 5
2026-07-25 15:47:08 -07:00
Simon Willison
481df7ff6d Shorten link text in changelog 1.0a37 2026-07-14 09:31:28 -07:00
Simon Willison
2ffd8a860e Release 1.0a37
Refs #2831, #2832, #2841, #2842, #2843, #2846
2026-07-14 09:28:29 -07:00
Simon Willison
8b7c942d5e Major performance boost for SQL permissions, closes #2832 2026-07-14 09:18:51 -07:00
TowyTowy
591b909a4d
Escape table names with [square] brackets, refs #2431 (#2846)
Several internal helpers quoted table names using SQLite [bracket]
identifiers built with an f-string, e.g. PRAGMA foreign_key_list([{table}]).
Bracket quoting cannot escape a "]" character, so any table whose name
contains "]" (for example "[foo]" or "foo]") produced
"sqlite3.OperationalError: unrecognized token" - crashing schema
introspection at startup and 500-ing the table page.

Switch these call sites to the existing escape_sqlite() helper, which uses
"double quote" quoting with correct "" escaping (the same approach already
used elsewhere in the codebase and in the test suite):

- utils/internal_db.py: PRAGMA foreign_key_list / index_list
- utils/__init__.py: get_outbound_foreign_keys
- database.py: table_counts count query
- facets.py: default "select * from" SQL

Added a regression test covering table names with "]" characters.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-14 08:53:45 -07:00