
SQLite 3.53.4 - Élevé - Local - Fuite d'informations - Incohérence de taille de page WAL/DB sur la fin de page non initialisée
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-wal-pagesize
Classe : Fuite d'informations Portée : Locale
SQLite 3.53.4 (b09c88c) effectue toujours une lecture courte d'une trame WAL dans une page de pager complète sans memset de la queue. walIndexRecover accepte toute taille de page WAL puissance de deux dans [512, SQLITE_MAX_PAGE_SIZE] et ne la compare jamais à la taille de page de la base de données. Les emplacements pcache recyclés renvoient alors les octets de tas/page antérieurs via du SQL ordinaire.
Labo : .db en mode WAL avec pages de 4096, en-tête -wal frère avec taille de page 512, SELECT b FROM t a renvoyé 2000 octets. La queue au-delà de la trame de 512 octets était SQLITE-WAL-PAGESIZE-WITNESS. Pas de RCE.
| ID | pas encore de CVE |
| Classe | Fuite d'informations (queue de pager non initialisée via SQL) |
| Portée | Locale (.db non fiable plus -wal frère) |
| CWE | CWE-908, CWE-200 |
| CVSS | Élevé : 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Produit | SQLite (Hwaci) |
| Affecté | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69) ; SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| Auth | aucune (la victime ouvre les fichiers de l'attaquant) |
| Licence | GNU Affero GPL v3.0 |
| Labo | 127.0.0.1:18830 uniquement |
Livrer un .db en mode WAL plus un -wal frère dont la taille de page d'en-tête est une puissance de deux valide plus petite que celle de la base de données. La récupération l'accepte. sqlite3WalReadFrame ne copie que la taille de la trame WAL dans un tampon de pager dimensionné d'après le .db. Une cellule de feuille de table qui déclare une charge utile plus grande que cette trame est satisfaite depuis la queue pcache recyclée. SELECT / substr() / hex() sur ce blob renvoie les octets de pager/tas résiduels des pages antérieures dans le même processus.
L'incompatibilité inverse (WAL plus grand que le pager) donne SQLITE_CORRUPT au checkpoint. Ce résidu ne concerne que le chemin de lecture avec WAL plus petit. Pas de RCE.
Vingt chasses dans le code source de 3.53.4 après la matrice de résidus du tronc ultérieur. Winter l'a signalé sur le forum comme 2026-08-17T15:54:41Z. Le tronc f9b4ee3695 / branch-3.53 4fde87b2a0 (2026-08-16) est postérieur à cette GA (2026-07-24). sqlite3WalReadFrame sur ce pin est toujours (nOut>sz ? sz : nOut) sans memset de la queue.
Fausse piste : une cellule de feuille précoce était malformée et SELECT renvoyait SQLITE_CORRUPT rc=11. La cellule qui fonctionne déclare 2000 octets de charge utile locale sur une trame de 512 octets dans une page de pager de 4096 octets.
cd lab
./run.sh
Compile SQLite 3.53.4 depuis l'archive source canonique. Compose sqlite-wal-pagesize. Publié sur 127.0.0.1:18830. Amorçe le pcache avec 48x4000 octets de lignes témoins, puis SELECT b FROM t sur la feuille en lecture courte.
SUCCESS sqlite-wal-pagesize how=wal-shortread-pcache-tail len=2000 rootpage=2 SQLITE-WAL-PAGESIZE-WITNESS
Comparer la taille de page de l'en-tête WAL à la taille de page de la base de données pendant la récupération. En cas de désaccord, refuser le WAL ou initialiser entièrement la page de pager :
if( nOut>sz ){
memset(pOut+sz, 0, nOut-sz);
nOut = sz;
}
Ce hunk est sur le tronc après cette GA. Il n'est pas dans 3.53.4.
b09c88c14082339b66c7b7158d609a771e64ca69)src/wal.c sqlite3WalReadFrame, walIndexRecoversrc/pager.c readDbPage