
SQLite 3.53.4 - Élevé - Local - Résidu de privilège - FULL JOIN USING ignore sqlite3AuthRead
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-fj-using-auth
Classe : Résidu de privilège Portée : Locale
SQLite 3.53.4 (b09c88c / SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc) - Hwaci
lookupName() réécrit une colonne FULL JOIN USING en coalesce(...) (TK_FUNCTION). sqlite3AuthRead ne s'exécute que pour TK_COLUMN / TK_TRIGGER, donc les colonnes USING ne reçoivent jamais de callback SQLITE_READ. Un embedder ayant installé sqlite3_set_authorizer et refusé/ignoré READ sur t2.x renvoie toujours cette colonne via SELECT x FROM t1 FULL JOIN t2 USING(x).
L'authorizer est désactivé à l'ouverture par défaut. Résidu de cette API C. Pas de RCE. FULL JOIN ON et LEFT JOIN USING restent refusés / sans fuite. coalesce(t2.x) explicite est toujours autorisé.
| ID | pas encore de CVE |
| Classe | Résidu de privilège (contournement de l'authorizer au niveau colonne) |
| Portée | Locale (embedder sqlite3_set_authorizer ; SQL attaquant) |
| CWE | CWE-863, CWE-284 |
| CVSS | Élevé : 7.5 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| Produit | SQLite (miroir GitHub sqlite/sqlite) |
| Affecté | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69). Le correctif authorizer FULL JOIN USING réservé à 3.54 (2cb2287768) n'est pas dans cette GA. |
| Auth | embedder ayant installé sqlite3_set_authorizer ; le callback par défaut est NULL |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18840 uniquement. Chaîne témoin. Pas de RCE. |
Contre un embedder ayant installé sqlite3_set_authorizer comme ACL par colonne, préparer SELECT x FROM t1 FULL JOIN t2 USING(x) (ou NATURAL FULL JOIN). SELECT x FROM t2 seul est refusé (SQLITE_AUTH 23). La forme FULL JOIN USING renvoie la colonne dont le READ est refusé. Aucun callback READ t2.x ne se déclenche.
L'authorizer est désactivé sauf si l'embedder en installe un. Le sqlite3_open par défaut n'est pas concerné par ce résidu. Pas de RCE.
Vingt chasses dans les sources de 3.53.4 après PHP. La skip list nommait déjà le check-in authorizer FULL JOIN USING de 3.54. Il manque toujours sur la dernière GA. pExpr->op vaut TK_FUNCTION à lookupname_end, donc la barrière AuthRead ne s'exécute jamais. WRC_Prune empêche aussi le walker de descendre dans les arguments de 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
Fausses pistes déjà consignées : considérer l'authorizer comme actif par défaut ; s'attendre à une fuite via LEFT JOIN USING ou FULL JOIN ON ; s'attendre à ce que coalesce(t2.x) explicite contourne AuthRead ; épingler 3.54.0 alors qu'elle était encore en draft.
cd lab
./run.sh
Compile l'amalgamation officielle sqlite-src-3530400. Le harness est lab/auth.c. Loopback 127.0.0.1:18840. Authorizer DENY READ t2.x. SELECT x FROM t2 refusé. SELECT x FROM t1 FULL JOIN t2 USING(x) renvoie le témoin, 0 READ t2.x. FULL JOIN ON refusé. LEFT JOIN USING sans fuite. La baseline IGNORE est NULL ; IGNORE FULL JOIN USING fuit toujours.
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
Boucler sqlite3AuthRead sur chaque enfant pFJMatch après la réécriture en coalesce, comme le fait le trunk 2cb2287768 / Git 5694c3bb pour 3.54. Autoriser uniquement a[0] (bbd69ce274) ne suffit pas. LEFT JOIN USING et FULL JOIN ON autorisent déjà ; ils ne sont pas concernés par ce résidu.
b09c88c14082339b66c7b7158d609a771e64ca69)src/resolve.c réécriture en coalesce de lookupName et barrière AuthReadsrc/auth.c sqlite3AuthRead / sqlite3AuthReadCol