
SQLite 3.53.4 — высокий — локальный — остаточная привилегия — FULL JOIN USING пропускает sqlite3AuthRead
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-fj-using-auth
Разбор: https://abraxaslabs.tech/research/sqlite-fj-using-auth
Класс: Остаточные привилегии Доступ: Локальный
SQLite 3.53.4 (b09c88c / SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc) — Hwaci
lookupName() переписывает столбец FULL JOIN USING в coalesce(...) (TK_FUNCTION). sqlite3AuthRead выполняется только для TK_COLUMN / TK_TRIGGER, поэтому столбцы USING никогда не получают обратный вызов SQLITE_READ. Встраиваемое приложение, установившее sqlite3_set_authorizer и запретившее (DENY/IGNORE) READ на t2.x, всё равно возвращает этот столбец через SELECT x FROM t1 FULL JOIN t2 USING(x).
Авторизатор отключён при открытии по умолчанию. Это остаток от того C API. Не RCE. FULL JOIN ON и LEFT JOIN USING остаются запрещёнными / без утечки. Явный coalesce(t2.x) по-прежнему проходит авторизацию.
| ID | CVE пока нет |
| Класс | Остаточные привилегии (пропуск авторизатора на уровне столбца) |
| Доступ | Локальный (встраиваемое приложение sqlite3_set_authorizer; SQL атакующего) |
| CWE | CWE-863, CWE-284 |
| CVSS | Высокий: 7.5 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| Продукт | SQLite (зеркало на GitHub sqlite/sqlite) |
| Затронуто | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69). Исправление авторизатора FULL JOIN USING, вошедшее только в 3.54 (2cb2287768), отсутствует в этом GA-релизе. |
| Авторизация | встраиваемое приложение установило sqlite3_set_authorizer; по умолчанию обратный вызов равен NULL |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:18840. Строка-свидетель. Не RCE. |
Против встраиваемого приложения, установившего sqlite3_set_authorizer в качестве ACL на уровне столбцов, подготовить SELECT x FROM t1 FULL JOIN t2 USING(x) (или NATURAL FULL JOIN). Простой SELECT x FROM t2 запрещён (SQLITE_AUTH 23). Форма FULL JOIN USING возвращает столбец, доступ к которому на чтение запрещён. Не срабатывает ни одного обратного вызова READ t2.x.
Авторизатор отключён, если встраиваемое приложение его не установило. Стандартный sqlite3_open не подвержен этому остатку. Не RCE.
Двадцать поисков по исходникам 3.53.4 после PHP. Список пропусков уже указывал на коммит проверки авторизатора FULL JOIN USING в 3.54. Он по-прежнему отсутствует в последнем GA-релизе. pExpr->op равен TK_FUNCTION в lookupname_end, поэтому проверка AuthRead никогда не выполняется. WRC_Prune также не даёт обходчику спуститься в аргументы coalesce.
lookupname_end:
if( cnt==1 ){
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pParse->db->xAuth
&& (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER)
){
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
}
#endif
Ошибочные повороты, уже зафиксированные: трактовка authorizer как включённого по умолчанию; ожидание, что LEFT JOIN USING или FULL JOIN ON приведут к утечке; ожидание, что явный coalesce(t2.x) пропустит AuthRead; закрепление версии 3.54.0, пока она ещё была черновиком.
cd lab
./run.sh
Собирает официальную амальгамацию sqlite-src-3530400. Тестовый стенд — lab/auth.c. Loopback 127.0.0.1:18840. Авторизатор DENY READ t2.x. SELECT x FROM t2 отклоняется. SELECT x FROM t1 FULL JOIN t2 USING(x) возвращает свидетельство, 0 READ t2.x. FULL JOIN ON отклоняется. LEFT JOIN USING без утечки. Базовая линия IGNORE — NULL; IGNORE FULL JOIN USING всё равно даёт утечку.
SUCCESS sqlite-fj-using-auth how=full-join-using-skip-authread baseline=denied fj-using=witness fj-on=denied left-using=no-leak SQLITE-FJ-USING-AUTH-WITNESS
Выполняйте цикл sqlite3AuthRead по каждому дочернему элементу pFJMatch после переписывания coalesce, как это делает trunk 2cb2287768 / Git 5694c3bb для 3.54. Авторизации только a[0] (bbd69ce274) недостаточно. LEFT JOIN USING и FULL JOIN ON уже авторизуются; они не являются этим остатком.
b09c88c14082339b66c7b7158d609a771e64ca69)src/resolve.c переписывание coalesce в lookupName и проверка AuthReadsrc/auth.c sqlite3AuthRead / sqlite3AuthReadCol