← All issues

[14] SWServer Invalid Iterator Dereference on Desynchronized Maps

Severity: Low | Component: Service Workers (SWServer) | 09f4248

Rated Low because the observable effect is a crash via dereferencing an end() iterator (Network process DoS), with no evidence of escalation to memory corruption — the iterator dereference target is determined by HashMap internals, not attacker-controlled data.

Adds iterator end() guards in two locations within SWServer::unregisterServiceWorkerClientInternal(), preventing dereference of invalid iterators when map lookups fail due to race-induced desynchronization.

Source/WebCore/workers/service/server/SWServer.cpp

auto clientsByRegistrableDomainIterator = m_clientsByRegistrableDomain.find(clientRegistrableDomain);
ASSERT(clientsByRegistrableDomainIterator != m_clientsByRegistrableDomain.end());
- auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
- clientsForRegistrableDomain.remove(clientIdentifier);
- if (clientsForRegistrableDomain.isEmpty())
- m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
+ if (clientsByRegistrableDomainIterator != m_clientsByRegistrableDomain.end()) {
+ auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
+ clientsForRegistrableDomain.remove(clientIdentifier);
+ if (clientsForRegistrableDomain.isEmpty())
+ m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
+ }
auto iterator = protectedThis->m_clientIdentifiersPerOrigin.find(clientOrigin);
ASSERT(iterator != protectedThis->m_clientIdentifiersPerOrigin.end());
- iterator->value.terminateServiceWorkersTimer->startOneShot(protectedThis->m_isProcessTerminationDelayEnabled ? defaultTerminationDelay : defaultFunctionalEventDuration);
+ if (iterator != protectedThis->m_clientIdentifiersPerOrigin.end())
+ iterator->value.terminateServiceWorkersTimer->startOneShot(protectedThis->m_isProcessTerminationDelayEnabled ? defaultTerminationDelay : defaultFunctionalEventDuration);

Missing iterator validity check before dereference in a race-prone map lookup path.

Service Workers are background scripts registered by web pages that intercept network requests. SWServer is the server-side component running in WebKit's Network process that tracks registered clients. It maintains multiple HashMaps (m_clientsByRegistrableDomain, m_clientIdentifiersPerOrigin, m_clientsById) that must remain synchronized. When a client disconnects, unregisterServiceWorkerClient() removes entries from these maps. A race condition occurs when the same client is unregistered more than once before map state is reconciled — the commit message confirms this is reproducible by calling unregisterServiceWorkerClient() twice.

Before the fix, unregisterServiceWorkerClientInternal() unconditionally dereferenced iterators from HashMap::find() without checking for end(). Due to race conditions where the internal maps could get out of sync — for example, a client being unregistered twice — the find() call could return end(), and the subsequent dereference would access invalid memory or crash.

🔒

Explores whether this crash can be escalated under realistic conditions

Subscribe to read more

🔒

Multiple reusable audit patterns identified, with concrete starting points for variant discovery across WebKit's multi-process client tracking

Subscribe to read more