← All reports

Enable storage site validation

Component: WebKit NetworkProcess storage | df8786e

Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp

+#define STORAGE_MESSAGE_CHECK(assertion, connection) do { \
+ if (!(assertion)) [[unlikely]] { \
+ RELEASE_LOG_FAULT(Storage, "%s: storage site validation failed", WTF_PRETTY_FUNCTION); \
+ return; \
+ } \
+} while (0)
+#define STORAGE_MESSAGE_CHECK_COMPLETION(assertion, connection, completion) do { \
+ if (!(assertion)) [[unlikely]] { \
+ RELEASE_LOG_FAULT(Storage, "%s: storage site validation failed", WTF_PRETTY_FUNCTION); \
+ return completion; \
+ } \
+} while (0)
 
void NetworkStorageManager::persisted(IPC::Connection& connection, const WebCore::ClientOrigin& origin, CompletionHandler<void(bool)>&& completionHandler)
{
assertIsCurrent(workQueue());
- MESSAGE_CHECK_COMPLETION(isSiteAllowedForConnection(connection.uniqueID(), WebCore::RegistrableDomain { origin.topOrigin }), connection, completionHandler(false));
+ STORAGE_MESSAGE_CHECK_COMPLETION(isSiteAllowedForConnection(connection.uniqueID(), WebCore::RegistrableDomain { origin.topOrigin }), connection, completionHandler(false));
...

WebKit runs web content in a sandboxed, less-trusted WebContent process, while storage — localStorage, IndexedDB, Cache API, the FileSystem API — lives in the more-privileged NetworkProcess and is accessed via IPC. MESSAGE_CHECK is WebKit's standard IPC sanity-check pattern: on assertion failure it assumes the sender is compromised or buggy and terminates the connection outright, acting as a hard security boundary.

This commit enables WebsiteDataStore::m_storageSiteValidationEnabled by default, so NetworkStorageManager validates the origin/site on incoming IPC messages, and introduces STORAGE_MESSAGE_CHECK replacing MESSAGE_CHECK across roughly 20 storage IPC handlers. The new macro is a deliberately weaker variant: on failure it logs a fault via RELEASE_LOG_FAULT and returns early, keeping the connection alive, so WebKit can observe false-positive rates in the field before promoting these checks back to full MESSAGE_CHECK — hence the FIXME.

A site-isolation boundary goes live in production: NetworkProcess now actively checks whether a WebContent process is permitted to touch a given site's storage before servicing the request. That closes a gap where a compromised renderer could otherwise read or write another origin's storage data, at the cost — deliberately, for now — of a soft failure mode rather than connection termination.

The forward-facing pattern is a soft-fail check replacing a hard-fail one in a security-enforcing path, where the early return leaves objects in a state the connection-kill path would never have produced. Narrow: across the ~20 converted handlers, look for any that mix MESSAGE_CHECK and STORAGE_MESSAGE_CHECK on related state — the match tell is a function whose soft-fail return happens after some state mutation but before its paired cleanup, or a completion handler invoked with a default value that a downstream caller treats as legitimate data. Wider: the same shape exists wherever a WebKit IPC handler validates late — audit other NetworkProcess message receivers for checks placed after object lookup or map insertion rather than at function entry, since a check that runs downstream of a side effect only prevents the final operation, not the state change. Widest: the general class is a validation predicate whose coverage is assumed to be complete because it appears in many handlers; enumerate the entry points reachable before isSiteAllowedForConnection/canConnectionAccessSiteForWebStorage runs — connection setup, session registration, and any handler that resolves an origin from a previously-registered identifier — since those paths establish the state the check later consults.