
SQLite 3.53.4 - Alta - Local - Fuga de información - Desajuste del tamaño de página WAL/DB en la cola de página no inicializada
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-wal-pagesize
Clase: Fuga de información Alcance: Local
SQLite 3.53.4 (b09c88c) todavía lee de forma corta un frame WAL dentro de una página completa del pager sin un memset de la cola. walIndexRecover acepta cualquier tamaño de página WAL potencia de dos en [512, SQLITE_MAX_PAGE_SIZE] y nunca lo compara con el tamaño de página de la base de datos. Los slots de pcache reciclados entonces devuelven bytes previos del heap/página a través de SQL ordinario.
Laboratorio: .db en modo WAL de 4096 páginas, página de cabecera del -wal hermano de 512, SELECT b FROM t devolvió 2000 bytes. La cola más allá del frame de 512 bytes era SQLITE-WAL-PAGESIZE-WITNESS. No es RCE.
| ID | sin CVE todavía |
| Clase | Fuga de información (cola del pager no inicializada a través de SQL) |
| Alcance | Local (.db no confiable más -wal hermano) |
| CWE | CWE-908, CWE-200 |
| CVSS | Alto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Producto | SQLite (Hwaci) |
| Afectado | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69); SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| Autenticación | ninguna (la víctima abre los archivos del atacante) |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1:18830 |
Entregar un .db en modo WAL más un -wal hermano cuyo tamaño de página de cabecera sea una potencia de dos válida menor que la de la base de datos. La recuperación lo acepta. sqlite3WalReadFrame copia solo el tamaño del frame WAL dentro de un búfer del pager dimensionado a partir del .db. Una celda de hoja de tabla que declara un payload mayor que ese frame se satisface desde la cola reciclada del pcache. SELECT / substr() / hex() sobre ese blob devuelve bytes sobrantes del pager/heap de páginas previas en el mismo proceso.
El desajuste inverso (WAL más grande que el pager) es SQLITE_CORRUPT en el checkpoint. Este sobrante es solo la ruta de lectura con WAL más pequeño. No es RCE.
Veinte búsquedas en el código fuente de 3.53.4 tras la matriz de sobrantes del trunk posterior. Winter lo reportó en el foro como 2026-08-17T15:54:41Z. El trunk f9b4ee3695 / branch-3.53 4fde87b2a0 (2026-08-16) es posterior a este GA (2026-07-24). sqlite3WalReadFrame en este pin sigue siendo (nOut>sz ? sz : nOut) sin memset de la cola.
Desvío: una celda de hoja temprana estaba malformada y SELECT devolvió SQLITE_CORRUPT rc=11. La celda que funciona declara 2000 bytes de payload local a través de un frame de 512 bytes en una página del pager de 4096 bytes.
cd lab
./run.sh
Compila SQLite 3.53.4 desde el zip de código fuente canónico. Compose sqlite-wal-pagesize. Publicado en 127.0.0.1:18830. Prepara el pcache con 48x4000 bytes de filas testigo, luego SELECT b FROM t sobre la hoja de lectura corta.
SUCCESS sqlite-wal-pagesize how=wal-shortread-pcache-tail len=2000 rootpage=2 SQLITE-WAL-PAGESIZE-WITNESS
Comparar el tamaño de página de la cabecera WAL con el tamaño de página de la base de datos durante la recuperación. Cuando no coincidan, rechazar el WAL o inicializar completamente la página del pager:
if( nOut>sz ){
memset(pOut+sz, 0, nOut-sz);
nOut = sz;
}
Ese fragmento está en el trunk después de este GA. No está en 3.53.4.
b09c88c14082339b66c7b7158d609a771e64ca69)src/wal.c sqlite3WalReadFrame, walIndexRecoversrc/pager.c readDbPage