
SQLite 3.53.4 - Élevé - Local - Crash - les CTE imbriquées contournent le plafond de profondeur de vue nNestSel
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-cte-nest
Write-up : https://abraxaslabs.tech/research/sqlite-cte-nest
Classe : Crash Portée : Locale
SQLite 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69, SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc) - Hwaci
sqlite3ResultSetOfSelect incrémente nNestSel et renvoie l'erreur VIEWs and/or subqueries nested too deep lorsque la chaîne atteint SQLITE_LIMIT_EXPR_DEPTH. Les VIEWs imbriquées sur ce commit atteignent déjà cette limite. L'attachement de CTE à select.c:5754 (sqlite3SrcItemAttachSubquery) n'incrémente pas nNestSel. selectExpander / sqlite3WalkSelect récursent ensuite la chaîne de CTE jusqu'à ce que la pile C s'effondre.
Une petite chaîne de CTE renvoie une ligne. Un FROM imbriqué à N=25000 déclenche un Recursion limit du parseur et ne plante pas. Les VIEWs imbriquées à .limit expr_depth 20 renvoient l'erreur too-deep. Une CTE à N=25000 provoque un stack-overflow ASan. Pas de RCE.
| ID | pas encore de CVE |
| Classe | Crash (stack-overflow ASan dans selectExpander ; RCE non démontré) |
| Portée | Locale (SQL non fiable ou schéma de CTE imbriquées) |
| CWE | CWE-674 |
| CVSS | Élevé : 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Produit | SQLite (miroir GitHub sqlite/sqlite) |
| Affecté | 3.53.4 (b09c88c) ; résidu du nNestSel des CTE du trunk ultérieur |
| Auth | SQL non fiable ou une chaîne WITH implantée |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18810 uniquement. Amalgamation ASan. Témoin de crash. |
Fournir une longue chaîne de CTE, sous forme de SQL ou de corps de VIEW sur un .db non fiable :
WITH c0 AS (SELECT 1),
c1 AS (SELECT * FROM c0),
...
cN AS (SELECT * FROM cN-1)
SELECT * FROM cN;
selectExpander parcourt chaque CTE comme une sous-requête FROM imbriquée. nNestSel ne bouge jamais. Le processus hôte meurt sur la pile C. Les VIEW imbriquées sont déjà plafonnées. Les FROM imbriqués atteignent la limite de récursion du parseur. Ce reliquat est le chemin d'attache des CTE. SQLite n'évalue pas les noms de CTE dans un shell. Crash, pas RCE.
Vingt recherches de sources sur https://github.com/sqlite/sqlite tag https://github.com/sqlite/sqlite/releases/tag/version-3.53.4. Les VIEW imbriquées étaient plafonnées sur ce pin (3f3fb9b638 / branch-3.53 38430aa5ed, 2026-06-16). L'attache des CTE ne l'était pas. Le trunk f547308713 (2026-10-05) est postérieur à cette GA.
Fausses pistes déjà consignées : traiter les VIEW imbriquées comme le crash (elles renvoient une erreur trop profonde) ; traiter le FROM imbriqué N=25000 comme le crash (parseur Recursion limit) ; prendre une chaîne de 5 CTE comme preuve que le plafond s'applique.
cd lab
./run.sh
Archive officiel sqlite-src-3530400, amalgamation ASan, compose sqlite-cte-nest, publié sur 127.0.0.1:18810. Liez-le à l'interface loopback. Ne pointez pas ceci vers le SQLite de quelqu'un d'autre.
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
Incrémenter nNestSel lors de l'attachement d'une CTE, comme le fait déjà sqlite3ResultSetOfSelect pour les VIEW, et lever une erreur au niveau de SQLITE_LIMIT_EXPR_DEPTH. Le trunk f547308713 (2026-10-05, « Limit the depth of recursion for CTEs using SQLITE_LIMIT_EXPR_DEPTH ») relève de ce type de correctif. Il n'est pas présent dans la 3.53.4.
b09c88c14082339b66c7b7158d609a771e64ca69)2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bccsrc/select.c sqlite3ResultSetOfSelect (nNestSel++), attachement de CTE :5754src/walker.c parcours de sous-requête sqlite3WalkSelectFromselectExpander / sqlite3SelectExpand2026-10-04T04:58:58Z ; trunk f547308713