CVE-2017-0236
Description
A remote code execution vulnerability exists in Microsoft Edge in the way that the Chakra JavaScript engine renders when handling objects in memory, aka "Scripting Engine Memory Corruption Vulnerability." This CVE ID is unique from CVE-2017-0224, CVE-2017-0228, CVE-2017-0229, CVE-2017-0230, CVE-2017-0234, CVE-2017-0235, and CVE-2017-0238.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A memory corruption vulnerability in Microsoft Edge's Chakra engine allows remote code execution via crafted web content.
Vulnerability
The vulnerability is a memory corruption issue in the Chakra JavaScript engine used by Microsoft Edge. It occurs when the engine improperly handles objects in memory, specifically during array buffer detach operations and array length mutation, leading to a use-after-free or heap corruption condition. Affected versions include Microsoft Edge on all supported Windows 10 versions (32-bit and x64-based systems) as of May 2017 [1][2].
Exploitation
An attacker can exploit this vulnerability by hosting a specially crafted website that triggers the memory corruption when a user visits the site using Microsoft Edge. No authentication or user interaction beyond browsing is required; the attacker only needs to convince the user to view the malicious page. The vulnerability is triggered during JavaScript execution when the Chakra engine processes array buffer detach and length mutation operations [3][4].
Impact
Successful exploitation allows the attacker to execute arbitrary code in the context of the current user. If the user has administrative privileges, the attacker could gain full control of the system, including the ability to install programs, view/change/delete data, or create new accounts with full user rights [1].
Mitigation
Microsoft released a security update as part of its May 2017 Patch Tuesday (MS17-011) that addresses this vulnerability. Users should apply the latest cumulative update for Microsoft Edge and Windows 10. The fix is also included in the ChakraCore servicing release on May 10, 2017 [4]. No workarounds are available; updating is the only mitigation [2].
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Microsoft.ChakraCoreNuGet | < 1.4.4 | 1.4.4 |
Affected products
4- Microsoft Corporation/Microsoft Edgev5Range: Windows 10 for 32-bit Systems, Windows 10 for x64-based Systems, Windows 10 Version 1511 for 32-bit Systems, Windows 10 Version 1511 for x64-based Systems, Windows 10 Version 1607 for 32-bit Systems, Windows 10 Version 1607 for x64-based Systems, Windows 10 Version 1703 for 32-bit Systems, and Windows 10 Version 1703 for x64-based Systems.
Patches
11ae7e3ce9551[CVE-2017-0236] Bug with array buffer detach
6 files changed · +159 −6
lib/Runtime/Library/ArrayBuffer.cpp+140 −5 modified@@ -38,7 +38,7 @@ namespace Js return toReturn; } - void ArrayBuffer::ClearParentsLength(ArrayBufferParent* parent) + void ArrayBuffer::DetachBufferFromParent(ArrayBufferParent* parent) { if (parent == nullptr) { @@ -48,23 +48,158 @@ namespace Js switch (JavascriptOperators::GetTypeId(parent)) { case TypeIds_Int8Array: + if (Int8VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Int8VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Int8Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Int8VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Int8Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Uint8Array: + if (Uint8VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Uint8VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Uint8Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Uint8VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Uint8Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Uint8ClampedArray: + if (Uint8ClampedVirtualArray::Is(parent)) + { + if (VirtualTableInfo<Uint8ClampedVirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Uint8ClampedArray>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Uint8ClampedVirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Uint8ClampedArray>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Int16Array: + if (Int16VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Int16VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Int16Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Int16VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Int16Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Uint16Array: + if (Uint16VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Uint16VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Uint16Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Uint16VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Uint16Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Int32Array: + if (Int32VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Int32VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Int32Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Int32VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Int32Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Uint32Array: + if (Uint32VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Uint32VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Uint32Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Uint32VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Uint32Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Float32Array: + if (Float32VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Float32VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Float32Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Float32VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Float32Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Float64Array: + if (Float64VirtualArray::Is(parent)) + { + if (VirtualTableInfo<Float64VirtualArray>::HasVirtualTable(parent)) + { + VirtualTableInfo<Float64Array>::SetVirtualTable(parent); + } + else + { + Assert(VirtualTableInfo<CrossSiteObject<Float64VirtualArray>>::HasVirtualTable(parent)); + VirtualTableInfo<CrossSiteObject<Float64Array>>::SetVirtualTable(parent); + } + } + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); + break; + case TypeIds_Int64Array: case TypeIds_Uint64Array: case TypeIds_CharArray: case TypeIds_BoolArray: - TypedArrayBase::FromVar(parent)->length = 0; + TypedArrayBase::FromVar(parent)->ClearLengthAndBufferOnDetach(); break; case TypeIds_DataView: - DataView::FromVar(parent)->length = 0; + DataView::FromVar(parent)->ClearLengthAndBufferOnDetach(); break; default: @@ -90,14 +225,14 @@ namespace Js if (this->primaryParent != nullptr) { - this->ClearParentsLength(this->primaryParent->Get()); + this->DetachBufferFromParent(this->primaryParent->Get()); } if (this->otherParents != nullptr) { this->otherParents->Map([&](RecyclerWeakReference<ArrayBufferParent>* item) { - this->ClearParentsLength(item->Get()); + this->DetachBufferFromParent(item->Get()); }); }
lib/Runtime/Library/ArrayBuffer.h+1 −1 modified@@ -50,7 +50,7 @@ namespace Js DEFINE_VTABLE_CTOR_ABSTRACT(ArrayBuffer, ArrayBufferBase); #define MAX_ASMJS_ARRAYBUFFER_LENGTH 0x100000000 //4GB private: - void ClearParentsLength(ArrayBufferParent* parent); + void DetachBufferFromParent(ArrayBufferParent* parent); public: template <typename FreeFN> class ArrayBufferDetachedState : public ArrayBufferDetachedStateBase
lib/Runtime/Library/DataView.cpp+8 −0 modified@@ -666,6 +666,14 @@ namespace Js return FALSE; } + void DataView::ClearLengthAndBufferOnDetach() + { + AssertMsg(this->GetArrayBuffer()->IsDetached(), "Array buffer should be detached if we're calling this method"); + + this->length = 0; + this->buffer = nullptr; + } + #ifdef _M_ARM // Provide template specialization (only) for memory access at unaligned float/double address which causes data alignment exception otherwise. template<>
lib/Runtime/Library/DataView.h+1 −0 modified@@ -50,6 +50,7 @@ namespace Js } uint32 GetByteOffset() const { return byteOffset; } + void ClearLengthAndBufferOnDetach(); static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...); static Var EntryGetInt8(RecyclableObject* function, CallInfo callInfo, ...);
lib/Runtime/Library/TypedArray.cpp+8 −0 modified@@ -1117,6 +1117,14 @@ namespace Js } + void TypedArrayBase::ClearLengthAndBufferOnDetach() + { + AssertMsg(IsDetachedBuffer(), "Array buffer should be detached if we're calling this method"); + + this->length = 0; + this->buffer = nullptr; + } + Var TypedArrayBase::EntryGetterBuffer(RecyclableObject* function, CallInfo callInfo, ...) { PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
lib/Runtime/Library/TypedArray.h+1 −0 modified@@ -157,6 +157,7 @@ namespace Js uint32 GetBytesPerElement() const { return BYTES_PER_ELEMENT; } byte* GetByteBuffer() const { return buffer; }; bool IsDetachedBuffer() const { return this->GetArrayBuffer()->IsDetached(); } + void ClearLengthAndBufferOnDetach(); static Var CommonSet(Arguments& args); static Var CommonSubarray(Arguments& args);
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-0236nvdPatchVendor AdvisoryWEB
- www.securityfocus.com/bid/98234nvdThird Party AdvisoryVDB Entry
- github.com/advisories/GHSA-p3rw-88pp-w4jhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-0236ghsaADVISORY
- github.com/chakra-core/ChakraCore/commit/1ae7e3ce95515758b4cd7215cb4e48539a0f4031ghsaWEB
- github.com/chakra-core/ChakraCore/pull/2959ghsaWEB
- web.archive.org/web/20210125194440/http://www.securityfocus.com/bid/98234ghsaWEB
- web.archive.org/web/20211019191652/http://www.securitytracker.com/id/1038431ghsaWEB
- www.securitytracker.com/id/1038431nvd
News mentions
0No linked articles in our index yet.