FileSystemHandle IndexedDB storage
// LayoutTests WPT — race window the KeepAlive object closes:
const getRequest = store.get('key');
await requestWatcher(t, getRequest).wait_for('success');
await promiseForRequest(t, store.delete('key')); // record gone
await promiseForTransaction(t, tx);
const retrieved = getRequest.result; // KeepAlive must still hold FSM ref here
assert_true(await handle.isSameEntry(retrieved));
File System Access API는 페이지에 사용자 로컬 파일시스템 항목에 대한 지속적인 handle을 부여합니다. IndexedDB는 Structured Clone Algorithm을 통해 JS 값을 직렬화합니다. Handle이 IDB를 통해 round-trip할 수 있으면, 페이지는 파일시스템 참조를 영구 저장하고 비동기적으로 live handle을 복원하는 것이 가능합니다. WebKit의 multi-process 모델에서 NetworkProcess는 신뢰할 수 있는 storage broker 역할을 맡으며, FileSystemStorageManager와 SQLiteIDBBackingStore를 소유합니다. WebProcess는 신뢰할 수 없는 프로세스로 취급됩니다.
이 commit은 FileSystemFileHandle과 FileSystemDirectoryHandle 객체를 IndexedDB에 저장하는 기능을 구현합니다. Wire form에서는 handle의 global identifier만 직렬화됩니다. put 시점에는 NetworkProcess가 FileSystemStorageManager를 통해 전체 (kind, path, name) 레코드를 조회하고, get 시점에는 이를 다시 연결합니다. WebProcess 측에는 새로운 ref-counting 객체인 FileSystemHandleStorageKeepAlive가 도입되었습니다. 이 객체는 IPC를 통해 NetworkProcess 측 FSM 참조를 유지하며, 비동기 JS 역직렬화 도중 UAF가 발생하지 않도록 보호하는 역할을 담당합니다. 보호 대상은 IDB 결과가 전달된 시점부터 JS가 request.result를 처음 읽는 시점까지의 gap입니다.
Significance
File System Access와 IndexedDB라는 두 고권한 API를 WebProcess/NetworkProcess 경계를 넘어 연결하면서, 새로운 IPC surface, ref-counting 서브시스템, cross-origin 검증 경로가 도입되었습니다. 이 세 영역은 모두 과거에 security bug가 자주 발견된 곳입니다.
Audit directions
FileSystemHandleStorageKeepAliveref-counting path. Double-free 또는 under-release가 발생하면, WebProcess가 dangling filesystem reference를 보유한 상태로 남을 수 있습니다. 악의적인 WebProcess는 자신이 등록한 적 없는 identifier에 대해RemoveGlobalIdentifierReferences를 전송할 수 있는지 탐색할 가능성이 있습니다. 또한 중복 제거 메시지를 반복 전송해 ref count를 음수로 만들려 시도하는 경우도 점검해야 합니다.- 'Stash resolved records on IDBValue' side channel.
IDBValue에 부착된 NetworkProcess 내부 상태는 IPC 직렬화를 거치지 않습니다. cursor iteration이나 batchedgetAllRecords경로에서 이 stash된 레코드를 올바르게 전파하거나 초기화하지 못하면, handle metadata가 트랜잭션 경계나 origin을 넘어 노출될 가능성이 있습니다. - Origin isolation.
clientOrigin은IDBResultData를 통해 전달되며, IPC 직렬화 대상이 아닙니다. 이 값이 어떤 FSM 항목을 등록할지를 결정합니다.getRecordSuccess,getAllRecordsSuccess,openCursorSuccess,iterateCursorSuccess는 각각 독립적으로 이 origin을 전달합니다. 어느 한 경로에서 origin이 누락되거나 잘못 전달되면, cross-origin handle 접근이 가능해질 수 있습니다. SQLiteMemoryIDBBackingStorestub (private browsing에서 사용되는 in-memory 변형)은FileSystemHandleRecords를 명시적으로 구현하지 않습니다. dangling identifier와 함께 조용히 성공 처리되는 대신, handle storage를 올바르게 거부하거나 무시하는지 점검해야 합니다.