WebKit - 'ContainerNode::parserInsertBefore' Universal Cross-Site Scripting

EDB-ID: 42066
Author: Google Security Research
Published: 2017-05-25
CVE: CVE-2017-2508
Type: Webapps
Platform: Multiple
Aliases: N/A
Advisory/Source: Link
Tags: Cross-Site Scripting (XSS)
Vulnerable App: N/A

 https://bugs.chromium.org/p/project-zero/issues/detail?id=1146 
https://bugs.chromium.org/p/chromium/issues/detail?id=519558

VULNERABILITY DETAILS
From /WebKit/Source/core/dom/ContainerNode.cpp:

----------------
void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& nextChild)
{
(...)
while (RefPtrWillBeRawPtr<ContainerNode> parent = newChild->parentNode())
parent->parserRemoveChild(*newChild);

if (document() != newChild->document())
document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);

{
EventDispatchForbiddenScope assertNoEventDispatch;
ScriptForbiddenScope forbidScript;

treeScope().adoptIfNeeded(*newChild);
insertBeforeCommon(nextChild, *newChild);
newChild->updateAncestorConnectedSubframeCountForInsertion();
ChildListMutationScope(*this).childAdded(*newChild);
}

notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
}
----------------

|parserRemoveChild| can run script, and it can remove |nextChild| from DOM or move the node around. When this happens, the tree will be in an inconsistent state after the |insertBeforeCommon| call, allowing an attacker to bypass the frame restrictions.


Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42066.zip

Related Posts