
SQLite 3.53.4 — высокий — локальный — сбой — вложенные CTE обходят ограничение глубины представления nNestSel
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-cte-nest
Разбор: https://abraxaslabs.tech/research/sqlite-cte-nest
Класс: Crash Доступ: Локальный
SQLite 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69, SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc) - Hwaci
sqlite3ResultSetOfSelect увеличивает nNestSel и выдаёт ошибку VIEWs and/or subqueries nested too deep, когда цепочка достигает SQLITE_LIMIT_EXPR_DEPTH. Вложенные VIEW на этой сборке уже упираются в этот предел. Присоединение CTE в select.c:5754 (sqlite3SrcItemAttachSubquery) не увеличивает nNestSel. Затем selectExpander / sqlite3WalkSelect рекурсивно обходят цепочку CTE, пока не исчерпывается стек C.
Небольшая цепочка CTE возвращает строку. Вложенный FROM при N=25000 приводит к ошибке парсера Recursion limit и не вызывает падения. Вложенные VIEW при .limit expr_depth 20 также выдают ошибку too-deep. CTE при N=25000 — это переполнение стека под ASan. Не RCE.
| ID | CVE пока нет |
| Класс | Crash (переполнение стека под ASan в selectExpander; RCE не продемонстрирован) |
| Доступ | Локальный (недоверенный SQL или схема с вложенными CTE) |
| CWE | CWE-674 |
| CVSS | High: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Продукт | SQLite (зеркало на GitHub sqlite/sqlite) |
| Затронуто | 3.53.4 (b09c88c); остаток от более позднего nNestSel для CTE в trunk |
| Аутентификация | недоверенный SQL или внедрённая цепочка WITH |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:18810. ASan-амальгамация. Свидетельство падения. |
Подать длинную цепочку CTE — в виде SQL или как тело VIEW в недоверенном .db:
WITH c0 AS (SELECT 1),
c1 AS (SELECT * FROM c0),
...
cN AS (SELECT * FROM cN-1)
SELECT * FROM cN;
selectExpander обходит каждый CTE как вложенный подзапрос FROM. nNestSel никогда не сдвигается. Хост-процесс погибает на стеке C. Вложенные VIEW уже ограничены. Вложенный FROM упирается в лимит рекурсии парсера. Этот остаток — путь привязки CTE. SQLite не вычисляет имена CTE в оболочку. Падение, а не RCE.
Двадцать поисков по исходникам https://github.com/sqlite/sqlite тега https://github.com/sqlite/sqlite/releases/tag/version-3.53.4. Вложенные VIEW были ограничены на этом пине (3f3fb9b638 / branch-3.53 38430aa5ed, 2026-06-16). Привязка CTE — нет. Trunk f547308713 (2026-10-05) идёт после этого GA.
Уже зафиксированные неверные пути: считать вложенные VIEW причиной падения (они выдают ошибку too-deep); считать вложенный FROM N=25000 причиной падения (парсер Recursion limit); принимать цепочку из 5 CTE за доказательство применимости ограничения.
cd lab
./run.sh
Официальный zip-архив sqlite-src-3530400, ASan-амальгама, compose sqlite-cte-nest, опубликован на 127.0.0.1:18810. Привяжите его к loopback. Не направляйте это на чужой SQLite.
SUCCESS sqlite-cte-nest how=asan-stack-overflow crash-n=25000 small-cte=ok nested-views=too-deep nested-from=rejected SQLITE-CTE-NEST-WITNESS
Увеличивайте nNestSel при присоединении CTE так же, как это уже делает sqlite3ResultSetOfSelect для VIEW, и выдавайте ошибку при SQLITE_LIMIT_EXPR_DEPTH. Trunk f547308713 (2026-10-05, "Limit the depth of recursion for CTEs using SQLITE_LIMIT_EXPR_DEPTH") относится к этому классу патчей. Его нет в 3.53.4.
b09c88c14082339b66c7b7158d609a771e64ca69)2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bccsrc/select.c sqlite3ResultSetOfSelect (nNestSel++), присоединение CTE :5754src/walker.c обход подзапросов в sqlite3WalkSelectFromselectExpander / sqlite3SelectExpand2026-10-04T04:58:58Z; trunk f547308713