ThearchyHelios
|
2b5989ef00
|
K3b 复核修正(第 2 轮):VALUES、行构造器里的 (表达式).* 和交回复合类型的表值函数整份遮;记着别的会话 SQL 的视图、不只读表结构的 SHOW 和 EXPLAIN 整份遮
- VALUES 里的 (表达式).*(基线就有):Postgres 在 VALUES 里同样把复合类型、记录展开成好几列,LATERAL VALUES 按表值
函数认时一个元组项只算一列,column2 起的号码原样交给模型、落库。现在 (表达式).* 不只看选出项:树上任何位置的(VALUES、
行构造器、函数参数里的),以及 VALUES 里的 s.*、(s.*),读到遮罩列就整份遮。(表达式).* 的值只按那个表达式认,不再把 *
当成展开 FROM 的来源(没设遮罩的复合类型 (p.address).* 以前因此被整列遮)
- 同一类、复核没点到的:Postgres 里 FROM 中交回复合类型的表值函数。unnest 的数组元素是复合类型时展开成各个字段
(unnest(ARRAY[p.card]) 出 addr、tel,写了列名表也只改前几列的名字),不认得的函数只写了列名、没写类型的列名表
(jsonb_populate_record(NULL::contact, …) AS r(a) 后面的字段照原名出),读到遮罩列的整份遮(_spreads_record);拆普通
数组的 unnest 也一样(元素类型 SQL 里看不出,多遮)。写了带类型列定义的照写的认
- Oracle 的 JSON 点号、对象类型的属性(t.profile.tel,解析器读成库、表、列):前面几段也算列,以前只认 tel,号码原样交出
- 记着别的会话 SQL 原文、被锁那一行的值的来源补进 INDIRECT_NAMES(工具边界和可验证报告共用一份):MySQL 的 INNODB_TRX、
OPTIMIZER_TRACE,MariaDB 的 INNODB_LOCKS、QUERY_CACHE_INFO,Oracle 的 V$ / GV$ / X$ 一律算、AWR 历史、SQL 调优集和
调优顾问、固定的执行计划和 SQL Profile、闪回事务,DBMS_XPLAN、DBMS_SQLTUNE 这类出报告的包
- 不是查询的语句(_reads_beyond):只读表结构的 SHOW(表、列、索引、库、表状态、建库语句)、DESCRIBE / EXPLAIN 一张表
照常,别的 SHOW(ENGINE INNODB STATUS、BINLOG / RELAYLOG EVENTS、REPLICA STATUS、WARNINGS、PROFILES、CREATE TABLE /
VIEW、TRIGGERS……)、EXPLAIN 一条语句(MySQL 把只有一行的表的值代进计划里的条件,8.0 实测)不逐个认,一律整份遮。
SHOW CREATE TABLE 不算只读表结构:对视图交回的是视图定义(WHERE 里写死的号码,8.0 实测),以前因为写着 TABLE x 本来
就整份遮,照旧;SHOW TABLE STATUS 以前同样因此整份遮,现在照常
- 质询模块说明的已知局限同步;补一条:视图、函数、约束定义里写死的字面量(information_schema.views、pg_views、
pg_get_viewdef()……)不认,照常交给 agent
补测试:VALUES × LATERAL / JOIN LATERAL / CTE / FROM / 匿名 ROW / 整行 / 表和子查询的 *,函数参数里的 (表达式).*,
没碰遮罩列的对照;交回复合类型的表值函数九种写法和三种照旧按名字认的对照;Oracle 点号四种和两种对照;十九种视图和包、
十三种 SHOW、九种 EXPLAIN、十二种只读表结构的对照;核查 agent 真实查询工具上的端到端(Postgres 的 VALUES 展开、MySQL
的 INNODB_TRX 和 SHOW ENGINE INNODB STATUS)。逐项去掉实现((表达式).* 的取值、树上的 Dot、VALUES 里的 *、新名字、
_reads_beyond、只读表结构的豁免、SHOW CREATE TABLE、unnest、只写列名的列名表、三段名),对应的测试都变红。另在
Postgres 18、MySQL 8.0 临时实例上经核查 agent 的真实查询工具复跑复核的复现和上面这些写法(44 条),交给模型的、落库的、
通用工件接口给的都没有号码;169c500 上其中 23 条漏号码。
|
2026-10-12 10:50:40 +08:00 |
|
ThearchyHelios
|
6a7e51b81b
|
K3 复核修正(第 2 轮):* 把遮罩列带进别的列名时按展开落到的位置遮;函数参数里的 JSON 箭头认作遮罩列;agent 查到的遮罩值和报告里的分开记,上限收满也不丢
- * 改名(复核点名的 blocker):WITH t(a, b, …) AS (SELECT * …) 这类列名表、UNION 后一支的 *、FROM 子查询或 LATERAL
的列名表、标量子查询和 ARRAY 子查询里的 *,以前 * 本身不算取自哪一列,原值原样交给核查 agent、落库,第二道防线也
认不出。现在 * 带出遮罩列的值时,它展开落到的那几列都算(masking._star_places):只展开一个来源、每一列都数得清的
按位置只遮取自遮罩列的那几列——子查询按选出项数,数据源里的表按查询当时冻结的表结构数(_schema_columns;工具边界
用数据源的 schema_cache,事后按快照的 schema_artifact,是同一份),几张列一样的月度表 SELECT * 连起来汇总,金额照常;
数不清的(没有表结构、列数对不上、几个来源)整段遮。表结构只用来数位置,不用来断定表里没有遮罩列。标量子查询里的 *
按 _value_columns 展开(展开数据源里的表一律算),EXISTS 里的 * 不算;递归的 CTE 不会绕不出来;带 EXCLUDE / REPLACE
的 * 不按位置数
- JSON 箭头:函数参数里没写表名的 col->'path' 被 sqlglot 解析成以 col 为参数的 lambda,_value_columns 把 lambda 的
参数名照列名收。SQLite json_each(profile->'$.tels')、Postgres jsonb_array_elements_text(profile->'tels')、MySQL
JSON_UNQUOTE(profile->'$.tel') 这几种拆开、取出来的值在工具边界就遮
- 上限:run_verify_agent 以前先把调用方交进来的报告快照值并进 seen,收满 SECRETS_MAX 之后 agent 查到的值并不进去,后面
的查询、回答时的第二道防线都认不出。现在两份分开记(masking.SeenValues:given / found),查询工具按值遮、交回调用方
(VerifyOutcome.masked_values)时合起来,agent 查到的在前;反方审稿理由的按值遮也改成 agent 查到的先收
- 已知局限写进 inquiry 模块说明:表结构过期、列数没变却换了次序或改了名时可能数错;EXCEPT 后一支照 UNION 算(多遮)
测试:新增 test_masking_star_renames(真跑 SQLite 的各种 * 改名、按表结构数位置、表结构对不上、快照记着的表结构),
工具边界(交给模型的、落库的、通用工件接口)和审批质询端到端的 * 改名、JSON 箭头、上限收满;每处实现都做过去掉之后
测试变红的验证。
|
2026-10-06 20:29:58 +08:00 |
|