Chrome Universal XSS by circumventing the unload event ( CVE-2016-1623)

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

Description

VULNERABILITY DETAILS

From /third_party/WebKit/Source/core/dom/Document.cpp: `` void Document::dispatchUnloadEvents() { PluginScriptForbiddenScope forbidPluginDestructorScripting; RefPtrWillBeRawPtrprotect(this); if (m_parser) m_parser->stopParsing();

if (m_loadEventProgress == LoadEventNotRun)
return;

if (m_loadEventProgress <= UnloadEventInProgress) {
(...)
 if (m_loadEventProgress < PageHideInProgress) {
(...)
}
 m_loadEventProgress = UnloadEventHandled;
}

(...) } ``

If this method is called while the document's |m_loadEventProgress| is still at |LoadEventNotRun| then it returns without advancing |m_loadEventProgress|. It is possible to take this branch by calling document. open() (which sets |m_loadEventProgress| to LoadEventNotRun), and then navigating the document without the body element (the presence of which would allow |m_loadEventProgress| to change to BeforeUnloadEventCompleted before Document::dispatchUnloadEvents is called).

Since FrameLoader::prepareForCommit relies on Document::dispatchUnloadEvents to advance |m_loadEventProgress| to block the creation of new frames, this allows an attacker to attach subframes that will persist in the frame tree of a cross-origin document.

VERSION

Chrome 47.0.2526.106 (Stable) Chrome 48.0.2564.71 (Beta) Chrome 49.0.2618.8.0 (Dev) Chromium 49.0.2621.0 (Release build compiled today)

Attachment: CVE-2016-1623.zip