
SQLite 3.53.4 — высокий уровень — локальная — утечка информации — несоответствие размера страницы WAL/DB, неинициализированный хвост страницы
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-wal-pagesize
Класс: Утечка информации Охват: Локальный
SQLite 3.53.4 (b09c88c) по-прежнему выполняет короткое чтение кадра WAL в полную страницу pager без обнуления хвоста. walIndexRecover принимает любой размер страницы WAL, являющийся степенью двойки, в диапазоне [512, SQLITE_MAX_PAGE_SIZE] и никогда не сравнивает его с размером страницы базы данных. Переиспользуемые слоты pcache затем возвращают предыдущие байты кучи/страницы через обычный SQL.
Лаборатория: .db в режиме WAL со страницами 4096, соседний -wal с размером страницы в заголовке 512, SELECT b FROM t вернул 2000 байт. Хвост после 512-байтового кадра был SQLITE-WAL-PAGESIZE-WITNESS. Не RCE.
| ID | CVE пока нет |
| Класс | Утечка информации (неинициализированный хвост pager через SQL) |
| Охват | Локальный (недоверенный .db плюс соседний -wal) |
| CWE | CWE-908, CWE-200 |
| CVSS | Высокий: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Продукт | SQLite (Hwaci) |
| Затронуто | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69); SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| Аутентификация | отсутствует (жертва открывает файлы атакующего) |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:18830 |
Поставить .db в режиме WAL вместе с соседним -wal, размер страницы в заголовке которого — меньшая допустимая степень двойки, чем у базы данных. Восстановление это принимает. sqlite3WalReadFrame копирует только размер кадра WAL в буфер pager, размер которого задан из .db. Ячейка листа таблицы, заявляющая полезную нагрузку больше этого кадра, удовлетворяется из переиспользуемого хвоста pcache. SELECT / substr() / hex() по этому blob возвращает оставшиеся байты pager/кучи от предыдущих страниц в том же процессе.
Обратное несоответствие (WAL больше pager) даёт SQLITE_CORRUPT при checkpoint. Этот остаток относится только к пути чтения с меньшим WAL. Не RCE.
Двадцать поисков по исходникам 3.53.4 после матрицы остатков в более позднем trunk. Winter сообщил об этом на форуме как 2026-08-17T15:54:41Z. Trunk f9b4ee3695 / branch-3.53 4fde87b2a0 (2026-08-16) идёт после этого GA (2026-07-24). sqlite3WalReadFrame на этом пине по-прежнему (nOut>sz ? sz : nOut) без memset хвоста.
Неверный путь: ранняя ячейка листа была некорректной, и SELECT вернул SQLITE_CORRUPT rc=11. Работающая ячейка заявляет 2000 байт локальной полезной нагрузки в 512-байтовом кадре на странице pager размером 4096 байт.
cd lab
./run.sh
Собирает SQLite 3.53.4 из канонического zip-архива исходников. Compose sqlite-wal-pagesize. Публикуется на 127.0.0.1:18830. Прогревает pcache 48 строками-свидетелями по 4000 байт, затем SELECT b FROM t по листу с коротким чтением.
SUCCESS sqlite-wal-pagesize how=wal-shortread-pcache-tail len=2000 rootpage=2 SQLITE-WAL-PAGESIZE-WITNESS
Сравнивать размер страницы из заголовка WAL с размером страницы базы данных во время восстановления. Когда они не совпадают, отклонять WAL или полностью инициализировать страницу pager:
if( nOut>sz ){
memset(pOut+sz, 0, nOut-sz);
nOut = sz;
}
Этот хунк находится в trunk после этого GA. В 3.53.4 его нет.
b09c88c14082339b66c7b7158d609a771e64ca69)src/wal.c sqlite3WalReadFrame, walIndexRecoversrc/pager.c readDbPage