[7] IndexedDB Connection/Transaction Identifier Confusion
Rated High because the diff fixes broker-side IDB registries that dereferenced renderer-supplied identifiers without rebinding to the sender; the resulting primitive is cross-renderer (effectively cross-origin) read, write, and destroy of IndexedDB records.
NetworkStorageManager's IDB IPC handlers looked up IDBDatabaseConnectionIdentifier/IDBResourceIdentifier via IDBStorageRegistry keyed only by handle. Any WebContent process could submit another renderer's identifier and have the NetworkProcess act on it.
Source/WebKit/NetworkProcess/storage/IDBStorageRegistry.cpp
Patch Details
connection() and transaction() now take IPC::Connection& and call isValidConnectionForIPC(), which resolves the database connection's owning client and compares ipcConnection() against the sender's uniqueID(). Every IDB IPC handler (establishTransaction, commitTransaction, putOrAdd, getRecord, openCursor, iterateCursor, etc.) is updated to thread IPC::Connection& through.
Missing sender-to-resource binding at an IPC trust boundary, where opaque identifiers minted by the broker are dereferenced without verifying that the originating IPC connection owns them.
Background
IndexedDB splits into a renderer-side WebCore layer and a NetworkProcess broker. IDBStorageRegistry holds m_connectionsToClient (keyed by IDBConnectionIdentifier, value records the originating IPC::Connection::UniqueID), m_connections (keyed by IDBDatabaseConnectionIdentifier), and m_transactions (keyed by IDBResourceIdentifier). IDBResourceIdentifier::connectionIdentifier() links back to a client connection. MESSAGE_CHECK terminates the offending child process on failure.
Analysis
Identifiers handed back to a renderer are capabilities; the broker must rebind on every call. Before the fix, WebContent A could send establishTransaction / putOrAdd / getRecord carrying WebContent B's identifier and have NetworkProcess execute against B's connection.
Read paths (getRecord, getAllRecords, getCount, openCursor, iterateCursor) exfiltrate B's records to A via the connection-to-client identifier embedded in the request; write paths (putOrAdd, deleteRecord, clearObjectStore, deleteObjectStore) corrupt B's databases; version-change handlers (didFireVersionChangeEvent, abortOpenAndUpgradeNeeded) perturb B's upgrade lifecycle. The primitive is logical, not memory-safety: the registry holds WeakPtrs and the looked-up objects are well-typed, so there's no UAF or type confusion — the impact is at the confidentiality and integrity layer. Notably, the commit pushes the check down into the lookup choke-point intentionally "so we don't forget to add such MESSAGE_CHECK when introducing new IPC."
This vulnerability weakens the IPC trust boundary that isolates one WebContent's IndexedDB state from another's — a same-origin/origin-partitioning bypass at the storage layer.
Audit directions
- Broker-side identifier-to-resource registries that don't re-verify ownership. Audit
CacheStorageRegistry,FileSystemStorageHandleRegistry,StorageAreaRegistry,ServiceWorkerStorageManager, and any*Registry/*ManagerunderSource/WebKit/NetworkProcess/storage/forget()/find()paths whose signatures lackIPC::Connection&. - IPC handlers that dereference an identifier via a registry without a preceding
MESSAGE_CHECK. GrepSource/WebKit/NetworkProcessandSource/WebKit/GPUProcessfor handler methods that take anIPC::Connection&plus an identifier. Start with GPUProcessRemoteDisplayList,RemoteRenderingBackend,RemoteWebGLresource identifiers. - Identifier types exposing
connectionIdentifier()/provenance. AuditIDBResourceIdentifier,WebTransportSessionIdentifier,WebPushIdentifierfor consumers that read provenance without checking against the liveIPC::Connection&. - TOCTOU within the work queue. If a registry lookup succeeds for connection A and the result is later re-used in a queued continuation after A has disconnected and the
UniqueIDis recycled, can a subsequent operation be misattributed? Verify the lifetime/uniqueness contract ofIPC::Connection::UniqueID.