abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-values-union
类别: 崩溃 可达性: 本地
SQLite 3.53.4 (b09c88c) - Hwaci
默认的 VALUES 使用协程。WITH(或 schema 重载,或非常量行)会强制 sqlite3MultiValues 走 UNION ALL 路径。当设置了 SF_Values 时,复合 SELECT 的长度检查会被跳过(parse.y:562-567)。随后足够大的行列表会被 SQLITE_LIMIT_EXPR_DEPTH 拒绝,而递归的 sqlite3ExprDeleteNN 会在错误清理路径上耗尽 C 栈。
普通的 5000 行 VALUES 没有问题。WITH 加 1000 行会干净地报错(Expression tree is too large)。WITH 加 300000 行会在 sqlite3ExprDeleteNN 中触发 ASan 栈溢出(rc=134)。不是 RCE。
| ID | 暂无 CVE |
| 类别 | 崩溃(ExprDelete 上的 ASan 栈溢出;未演示 RCE) |
| 可达性 | 本地(不可信 SQL,或 VIEW/TRIGGER 内的 VALUES) |
| CWE | CWE-674 |
| CVSS | 高危:7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 产品 | SQLite |
| 受影响版本 | 3.53.4(b09c88c14082339b66c7b7158d609a771e64ca69,SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc)。后续 trunk 中 VALUES 复合上限的遗留问题。 |
| 认证 | 攻击者 SQL,或一个会走 UNION ALL 回退路径的植入 schema |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18820。ASan 合并版。崩溃见证。 |
提供宿主将要 prepare 的不可信 SQL。在一个巨大的 VALUES 列表前加上 WITH,从而关闭协程路径。解析本应以表达式深度错误失败。但对该树的清理会在 sqlite3ExprDeleteNN 中递归,直到进程死亡。
当 VALUES 位于 VIEW 或 TRIGGER 中时(db->init.busy),同样的回退路径也会触发。宿主即嵌入方:一个 CLI、一个会 prepare 攻击者 SQL 的应用、一个打开恶意 .db 的服务。SQLite 不会把 VALUES 字节当作代码执行。崩溃本身就是发现。
对 github.com/sqlite/sqlite 标签 version-3.53.4 进行了二十次源码搜寻。跳过列表已排除了 CVE-2026-11824、session NPD、concat_ws、LOOKASIDE、JSON UAF、WAL-reset。默认 load_extension 是关闭的。解析器/VDBE 的遗留问题就是这处 VALUES UNION ALL 跳过加上一个递归析构函数。
if( (p->selFlags & (SF_MultiValue|SF_Values))==0
&& (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
&& cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
if( pParse->bHasWith
|| pParse->db->init.busy
|| exprListIsConstant(pParse,pRow)==0
...
){
/* The co-routine method cannot be used. Fall back to UNION ALL. */
...
pSelect->op = TK_ALL;
pSelect->pPrior = pLeft;
}
clearSelect() 以迭代方式遍历 pPrior。而 sqlite3ExprDeleteNN() 在 EP_Static 被设置时仍会对 pRight 和 pLeft 递归。
走过的弯路:带 WITH 的 1000 行会在文档所述的深度上限处干净报错,不会崩溃;需要 300000 行才能让析构深度耗尽 8 MiB 的 C 栈。普通 VALUES 仍走协程,是阴性对照。
cd lab
./run.sh
规范的 3.53.4 源码 zip,ASan sqlite3。Compose 服务 sqlite-values-union。发布在 127.0.0.1:18820。将其绑定到回环地址。
SUCCESS sqlite-values-union how=with-values-union-all-fallback-exprdelete rows=300000 crash=asan-stack-overflow plain=5000 depth-error=1000 SQLITE-VALUES-UNION-WITNESS
像其他复合结构一样,对 VALUES 施加 SQLITE_LIMIT_COMPOUND_SELECT 限制。在删除时以迭代方式遍历 UNION ALL 链,或在构建树之前就限制 EXPR_DEPTH,使清理过程不会在 C 栈上递归。后续 trunk(Bug 2026-10-04T05:34:47Z)在此 GA 版本之后。
b09c88c14082339b66c7b7158d609a771e64ca69)2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bccsrc/parse.y:562-567 当设置了 SF_Values 时跳过复合 SELECTsrc/insert.c:681-704 sqlite3MultiValues 的 UNION ALL 回退src/expr.c:1406-1430 递归的 sqlite3ExprDeleteNN