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 を導入し、t2.x に対する READ を DENY/IGNORE に設定した埋め込み先でも、SELECT x FROM t1 FULL JOIN t2 USING(x) によってその列が返されます。
Authorizer はデフォルトのオープン状態では無効です。これはその C API の取り残しです。RCE ではありません。FULL JOIN ON と LEFT JOIN USING は引き続き拒否され、漏洩もありません。明示的な coalesce(t2.x) は引き続き認可されます。
| ID | CVE 未割当 |
| 分類 | 権限の取り残し (列レベルの authorizer スキップ) |
| 到達範囲 | ローカル (埋め込み先の sqlite3_set_authorizer、攻撃者の SQL) |
| CWE | CWE-863, CWE-284 |
| CVSS | High: 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)。3.54 専用の authorizer FULL JOIN USING 修正 (2cb2287768) はこの GA には含まれていません。 |
| 認証 | 埋め込み先が sqlite3_set_authorizer を導入済み。デフォルトのコールバックは NULL |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1:18840 のみ。目撃文字列。RCE ではありません。 |
列 ACL として sqlite3_set_authorizer を導入した埋め込み先に対して、SELECT x FROM t1 FULL JOIN t2 USING(x) (または NATURAL FULL JOIN) を prepare します。素の SELECT x FROM t2 は拒否されます (SQLITE_AUTH 23)。FULL JOIN USING の形式では、READ が拒否された列が返されます。READ t2.x コールバックは一切発火しません。
Authorizer は埋め込み先が導入しない限り無効です。デフォルトの sqlite3_open はこの取り残しの対象ではありません。RCE ではありません。
PHP に続く 3.53.4 のソース探索 20 回目。スキップリストにはすでに 3.54 の FULL JOIN USING authorizer チェックインが挙げられていました。それは最新 GA でも依然として欠けています。lookupname_end において pExpr->op は TK_FUNCTION であるため、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 amalgamation をビルドします。ハーネスは lab/auth.c です。ループバック 127.0.0.1:18840。Authorizer は t2.x の READ を DENY します。SELECT x FROM t2 は拒否されます。SELECT x FROM t1 FULL JOIN t2 USING(x) は witness を返し、READ t2.x は 0 回です。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
coalesce 書き換えの後、trunk 2cb2287768 / Git 5694c3bb が 3.54 に対して行っているように、すべての pFJMatch 子に対して sqlite3AuthRead をループさせる。a[0] のみを認可する (bbd69ce274) だけでは不十分である。LEFT JOIN USING と FULL JOIN ON はすでに認可済みであり、これらはこの残存問題ではない。
b09c88c14082339b66c7b7158d609a771e64ca69)src/resolve.c の lookupName coalesce 書き換えと AuthRead ゲートsrc/auth.c の sqlite3AuthRead / sqlite3AuthReadCol