Chrome Universal XSS using late widget updates (CVE-2017-5006)

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



Among the things that Document::shutdown() does, |view()->dispose()| is called:

From /third_party/WebKit/Source/core/frame/FrameView.cpp: void FrameView::dispose() { (...) // FIXME: Do we need to do something here for OOPI? HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); // TODO(dcheng): It seems buggy that we can have an owner element that // points to another Widget. if (ownerElement && ownerElement->ownedWidget() == this) ownerElement->setWidget(nullptr); (...) }

In addition to what Daniel said, not clearing the owner's widget when it doesn't match the document's view is dangerous-and this logic means there are 2 cases:

  1. ownerElement->ownedWidget() == document_in_shutdown->view() The frame element's widget is cleared during Document::shutdown(). The widget update is suspended and executed in a safe state.

  2. ownerElement->ownedWidget() != document_in_shutdown->view() The frame element's widget is left intact during Document::shutdown(). Instead, it's cleared in LocalFrame::createView when a new view is created for the navigated frame shortly thereafter. This is unsafe because clearing the widget may destroy a plugin and run the script, allowing an attacker to violate invariants.


The attached exploit works in: Chrome 56.0.2924.21 (Beta)
Chrome 56.0.2924.18 (Dev)
Chromium 57.0.2948.0 + Pepper Flash (Release build compiled today)