fix: refuse the sandbox rather than quietly running it as the superuser

Both reviews landed on the same line independently. _as_role swaps the
credentials in the DSN with a regex, and when the pattern does not match
it returned the string unchanged. Two shapes miss it: no inline
credentials, and a unix socket URL. Either one is a legal DSN.

What that costs is not a broken test. The sandbox builds, every
assertion still passes, and bare_dsn is now the admin connection, so the
worst-case case runs the real script with --apply as a superuser against
the shared table. The verifier ran that command as a dry run to see what
it would have done: target public.llm_calls, 11 rows to delete. The case
would still have gone red on the exit code, after the rows were gone.

It raises now. There is also a second check that connects and compares
current_user, because a successful string substitution is not the same
as connecting as that role -- PGUSER and friends still override. The
whole design rests on that connection having no grant on the shared
table; a string comparison is too thin a thing to rest it on.

That check has to stay inside the try. Past it the cleanup statements
have already been merged into the fixture-level stack, and unwinding
again runs DROP OWNED BY twice, which has no IF EXISTS.

The catalog probe took any SQL and ran it on the admin connection. The
design claims withholding the DSN makes the boundary structural; that
was only true of the connection string, not of the capability. It takes
SELECT now.

--table's schema half is restricted to plain identifiers. Not a
security fix, since the name goes through a parameter and _quote: the
help text says complex identifiers are unsupported and the code was
accepting them anyway.
This commit is contained in:
2026-08-26 11:59:51 -04:00
parent bc0fcc4719
commit 58c4af28ea
6 changed files with 151 additions and 14 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
## 1.3.2(2026-08-26)
**本版不改库代码。** `tools/``tests/` 都不在 pip 包内(脚本随仓库分发,见 README),故 1.3.2 的 wheel 与 1.3.1 在库代码上**逐字节相同**。升级它不会改变任何库行为——本版的内容是运维脚本 `tools/telemetry_retention.py` 的一处契约扩展,以及测试隔离的重建。若你只用库本体,可以跳过本版。
**本版不改库代码。** `tools/``tests/` 都不在 pip 包内(脚本随仓库分发,见 README),故 1.3.2 的 wheel 与 1.3.1 **除版本号外没有任何差异**(`__version__` 与包元数据是唯一的改动)。升级它不会改变任何库行为——本版的内容是运维脚本 `tools/telemetry_retention.py` 的一处契约扩展,以及测试隔离的重建。若你只用库本体,可以跳过本版。
### 运维脚本:`--table` 让删除目标不再由连接环境决定(issue #18)