
SQLite 3.53.4 - 높음 - 로컬 - 크래시 - COLLATE 체인이 SQLITE_LIMIT_EXPR_DEPTH를 건너뜀
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-collate-depth
분류: 크래시 도달 범위: 로컬
SQLite 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69, SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc) - Hwaci
COLLATE 문법 액션은 sqlite3ExprCheckHeight를 호출하지 않는다. sqlite3ExprAddCollateToken은 nHeight가 여전히 1인 TK_COLLATE 노드를 할당한 다음, 이전 표현식을 pLeft에 매단다. 일반 연산자는 sqlite3PExpr을 거쳐 문서화된 SQLITE_LIMIT_EXPR_DEPTH(기본값 1000)를 적용받는다. 이 연산자는 그렇지 않다.
워커는 여전히 모든 pLeft에서 재귀한다. EP_Skip은 affinity를 위한 것이지 sqlite3WalkExprNN을 위한 것이 아니다. 50개 노드 체인은 1을 반환한다. 8k와 40k도 마찬가지로, 깊이 제한을 넘어선다. 120k는 sqlite3WalkExprNN에서 ASan 스택 오버플로를 일으킨다(rc=134). RCE는 아니다.
정식 트리는 https://sqlite.org/src 이다. GitHub sqlite/sqlite는 Fossil 미러이다. 공식 zip은 sqlite-src-3530400. 퍼블릭 도메인 라이브러리. 이 팩은 AGPLv3이다.
| ID | 아직 CVE 없음 |
| 분류 | 크래시 (sqlite3WalkExprNN에서 ASan 스택 오버플로; RCE는 입증되지 않음) |
| 도달 범위 | 로컬 (신뢰할 수 없는 SQL 또는 심어진 VIEW) |
| CWE | CWE-674, CWE-770 |
| CVSS | 높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 제품 | SQLite 3.53.4 |
| 영향받음 | 3.53.4 (b09c88c); 이후 트렁크 COLLATE 높이 검사의 잔재 |
| 인증 | 신뢰할 수 없는 SQL 또는 VIEW; 기본 load_extension은 꺼져 있음 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:18800 전용. ASan 아말감. 크래시 증거. |
긴 후위 COLLATE BINARY 체인을 SQL로 공급하거나, 신뢰할 수 없는 .db 내부의 VIEW에 심어둔다. 호스트 프로세스가 체인을 순회하다가 C 스택에서 죽는다. 문서화된 표현식 깊이 제한은 이 연산자에서 결코 실행되지 않는다.
SELECT 1 COLLATE BINARY COLLATE BINARY ... 만으로 충분하다. CREATE VIEW v AS SELECT 1 COLLATE BINARY ... 후 새 연결에서 SELECT * FROM v를 실행해도 같은 형태이다. 기본 SQLITE_LIMIT_SQL_LENGTH(1e9)는 이 랩에서 8 MB 스택을 오버플로시킨 약 1.8 MB 체인을 허용한다.
이것은 임베더 프로세스의 크래시이다. 명령 포인터 제어가 아니다. load_extension은 꺼져 있다.
OpenLiteSpeed 이후 SQLite 태그 version-3.53.4를 스무 번 소스 헌팅했다. 최신 GA이며, 3.54.0 초안이 아니다. sqlite.org/security.html은 신뢰할 수 없는 SQL과 신뢰할 수 없는 .db를 일급으로 취급한다. 기본 load_extension은 꺼져 있다.
COLLATE에 대한 parse.y는 세 줄이다:
expr(A) ::= expr(A) COLLATE ids(C). {
A = sqlite3ExprAddCollateToken(pParse, A, &C, 1);
}
sqlite3ExprAddCollateToken은 pNew->pLeft = pExpr와 EP_Collate|EP_Skip을 설정한다. sqlite3ExprAlloc은 nHeight = 1로 남겨두었다. sqlite3ExprCheckHeight는 없다. sqlite3PExpr은 다른 모든 이항 연산자에 대해 이 두 가지를 모두 수행한다.
잘못된 방향: 8k COLLATE를 크래시로 간주(1을 반환함); 40k를 크래시로 간주(역시 1을 반환했으며, SQLITE_LIMIT_EXPR_DEPTH 1000을 훨씬 넘김); ASan이 sqlite3WalkExprNN에서 죽기까지 120k가 필요했음.
이것은 핀에 남은 열네 개의 잔재 중 G1이다. 형제들은 다른 글들이다.
cd lab
./run.sh
공식 sqlite-src-3530400에서 만든 ASan 아말감(태그 version-3.53.4의 폴백 클론). Compose sqlite-collate-depth. 127.0.0.1:18800의 더미 HTTP. 루프백에 바인딩하라.
SUCCESS sqlite-collate-depth how=asan-stack-overflow control=50 crash-n=120000 SQLITE-COLLATE-DEPTH-WITNESS
50 COLLATE는 1을 반환한다. 8k와 40k도 1을 반환한다. 120k는 rc=134로 죽으며, sqlite3WalkExprNN에서 ASan 스택 오버플로이다. 핀 확인은 SELECT sqlite_version() / SELECT sqlite_source_id()이다.
pLeft를 연결한 후 COLLATE 노드에 sqlite3ExprCheckHeight를 호출하라, sqlite3PExpr이 이미 하는 방식대로. 자식으로부터 nHeight를 재계산하라. 후위 연산자도 여전히 표현식 트리이다.
트렁크 252c0b7bf5(2026-10-04)는 이 GA 이후이다.
b09c88c14082339b66c7b7158d609a771e64ca69)src/parse.y COLLATE 액션src/expr.c sqlite3ExprAddCollateToken, sqlite3ExprAlloc (nHeight = 1), sqlite3PExpr / sqlite3ExprCheckHeightsrc/walker.c sqlite3WalkExprNNsrc/sqliteLimit.h SQLITE_MAX_EXPR_DEPTH 기본값 1000