VYPR
High severity7.5NVD Advisory· Published May 12, 2017· Updated May 13, 2026

CVE-2017-0236

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.

PackageAffected versionsPatched versions
Microsoft.ChakraCoreNuGet
< 1.4.41.4.4

Affected products

4
  • Microsoft/Edge2 versions
    cpe:2.3:a:microsoft:edge:*:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:microsoft:edge:*:*:*:*:*:*:*:*
    • (no CPE)
  • ghsa-coords
    Range: < 1.4.4
  • Microsoft Corporation/Microsoft Edgev5
    Range: 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

1
1ae7e3ce9551

[CVE-2017-0236] Bug with array buffer detach

https://github.com/chakra-core/ChakraCoreRajat DuaMay 8, 2017via ghsa
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

News mentions

0

No linked articles in our index yet.