This is a friendly warning that your web-browser does not currently protecting your privacy and/or security as well as you might want. Click on this message to see more information about the issue(s) that were detected.

Google Chrome blink Serializer::do­Serialize bad cast

(This fix and CVE number for this issue are not known)

Synopsis

When serializing Java­Script objects for sending to another window using the post­Message method, the code in blink does not handle Symbol objects correctly and attempts to serialize this kind of object as a regular object, which results in a bad cast. An attacker that can trigger this issue may be able to execute arbitrary code.

Known affected versions, attack vectors and mitigations

Repro

<script>
  post­Message(Symbol());
</script>

Description

The repro causes a call to blink::V8Window::post­Message­Method­Custom (found in third_­party\webkit\source\bindings\core\v8\custom\v8windowcustom.cpp). This method creates a Serializer object for the "script value" of the symbol. In blink::`anonymous namespace'::Serializer::do­Serialize (found in third_­party\webkit\source\bindings\core\v8\serializedscriptvalue.cpp) the code attempts to determine the type of object being serialized and runs specific code to to serialize each type. This code does not distinguish between a Symbol and a regular object, and therefor runs code designed to handle the later to serialize the former. This results in a bad cast to a v8::Object.

Serializer::State­Base* Serializer::do­Serialize(v8::Handle<v8::Value> value, State­Base* next) { m_­writer.write­Reference­Count(m_­next­Object­Reference); uint32_t object­Reference; uint32_t array­Buffer­Index; if ((value->Is­Object() || value->Is­Date() || value->Is­Reg­Exp()) && m_­object­Pool.try­Get(value.As<v8::Object>(), &object­Reference)) { // Note that Is­Object() also detects wrappers (eg, it will catch the things // that we grey and write below). ASSERT(!value->Is­String()); m_­writer.write­Object­Reference(object­Reference); } else if (value.Is­Empty()) { return handle­Error(Input­Error, "The empty property name cannot be cloned.", next); } else if (value->Is­Undefined()) { m_­writer.write­Undefined(); /*** SNIP more special cases for various object types, but not Symbol ***/ } else { /*** No special case; treat as a regular object: the bad cast happens here ***/ v8::Handle<v8::Object> js­Object = value.As<v8::Object>(); /*** SNIP code proceeds to use the badly cast object ***/ } return 0; }

Exploit

The exploitability of a bad cast depends on many things, including what properties and methods the real object type and the object type it was cast to have, how much control an attacker has over the values of properties of the object, how the code proceeds to use the badly cast object, compiler optimizations, heap management, etc... Without further investigation it is impossible to say what an attacker could gain from exploiting this vulnerability. In this specific case, I did not have time to investigate exploitability on Google Chrome releases, so I cannot proof this is actually exploitable.

Time-line

© Copyright 2016 by Sky­Lined.
Creative Commons License This work is licensed under a Creative Commons Attribution-Non‑Commercial 4.0 International License.

Last updated on 2016-11-21.
If you find this web-site useful and would like to make a donation, you can send bitcoin to 183yyxa9s1s1f7JBp­PHPmz­Q346y91Rx5DX.