CVE-2018-8466
Description
A remote code execution vulnerability in Chakra scripting engine due to improper handling of objects in memory in Microsoft Edge and ChakraCore.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A remote code execution vulnerability in Chakra scripting engine due to improper handling of objects in memory in Microsoft Edge and ChakraCore.
Vulnerability
A remote code execution vulnerability exists in the Chakra scripting engine used by Microsoft Edge and ChakraCore, identified as CVE-2018-8466 [1]. The bug is a memory corruption issue where the engine improperly handles objects in memory, specifically in the JIT compiler's handling of arrays [4]. Affected versions include Microsoft Edge on multiple Windows 10 editions (32-bit and x64-based systems) as well as ChakraCore [2].
Exploitation
An attacker must host a specially crafted website that, when visited by a user running an affected version of Microsoft Edge, triggers the memory corruption [1][3]. The user is typically tricked into clicking a link or opening the malicious site. The vulnerability is exploited without authentication, requiring only user interaction [2]. The Chakra engine processes the crafted content, leading to memory corruption that can be leveraged for arbitrary code execution.
Impact
Successful exploitation allows an attacker to execute arbitrary code in the context of the current user. If the user has administrative privileges, the attacker can gain full control of the system, including installing programs, viewing or modifying data, and creating new accounts [1][3].
Mitigation
Microsoft released a security update on September 11, 2018, to address this vulnerability [3]. The fix is included in the cumulative update for Internet Explorer and Microsoft Edge, and in a ChakraCore update [4]. Users should apply the latest updates from Microsoft. No workarounds are documented, and the vulnerability is not listed on the CISA KEV.
- NVD - CVE-2018-8466
- Microsoft ChakraCore Scripting Engine CVE-2018-8466 Remote Memory Corruption Vulnerability
- Microsoft Edge Multiple Bugs Let Remote Users Execute Arbitrary Code, Obtain Potentially Sensitive Information, Gain Elevated Privileges, and Spoof Content on the Target System
- [CVE-2018-8466] Edge - Chakra: JIT: BailOutOnInvalidatedArrayHeadSegm… · chakra-core/ChakraCore@a404dec
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.11.1 | 1.11.1 |
Affected products
3- Range: ChakraCore
Patches
1a404dec65069[CVE-2018-8466] Edge - Chakra: JIT: BailOutOnInvalidatedArrayHeadSegment check bypass - Google, Inc.
3 files changed · +67 −8
lib/Backend/Lower.cpp+2 −0 modified@@ -14707,6 +14707,8 @@ IR::RegOpnd *Lowerer::GenerateArrayTest( { // Only DynamicObject is allowed (DynamicObject vtable is ensured) because some object types have special handling for // index properties - arguments object, string object, external object, etc. + // If other object types are also allowed in the future, corresponding changes will have to made to + // JavascriptArray::Jit_TryGetArrayForObjectWithArray as well. GenerateObjectTypeTest(baseOpnd, insertBeforeInstr, isNotObjectLabel); GenerateObjectHeaderInliningTest(baseOpnd, isNotArrayLabel, insertBeforeInstr); arrayOpnd = LoadObjectArray(baseOpnd, insertBeforeInstr);
lib/Runtime/Library/JavascriptArray.cpp+62 −7 modified@@ -596,11 +596,67 @@ using namespace Js; return scriptContext->GetLibrary()->GetArrayType(); } - JavascriptArray *JavascriptArray::GetArrayForArrayOrObjectWithArray(const Var var) + JavascriptArray *JavascriptArray::Jit_GetArrayForArrayOrObjectWithArray(const Var var) { bool isObjectWithArray; - TypeId arrayTypeId; - return GetArrayForArrayOrObjectWithArray(var, &isObjectWithArray, &arrayTypeId); + return Jit_GetArrayForArrayOrObjectWithArray(var, &isObjectWithArray); + } + + JavascriptArray *JavascriptArray::Jit_GetArrayForArrayOrObjectWithArray(const Var var, bool *const isObjectWithArrayRef) + { + Assert(var); + Assert(isObjectWithArrayRef); + + *isObjectWithArrayRef = false; + + if (!RecyclableObject::Is(var)) + { + return nullptr; + } + + JavascriptArray *array = nullptr; + INT_PTR vtable = VirtualTableInfoBase::GetVirtualTable(var); + if (!Jit_TryGetArrayForObjectWithArray(var, isObjectWithArrayRef, &vtable, &array)) + { + return nullptr; + } + + if (vtable != VirtualTableInfo<JavascriptArray>::Address && + vtable != VirtualTableInfo<CrossSiteObject<JavascriptArray>>::Address && + vtable != VirtualTableInfo<JavascriptNativeIntArray>::Address && + vtable != VirtualTableInfo<CrossSiteObject<JavascriptNativeIntArray>>::Address && + vtable != VirtualTableInfo<JavascriptNativeFloatArray>::Address && + vtable != VirtualTableInfo<CrossSiteObject<JavascriptNativeFloatArray>>::Address) + { + return nullptr; + } + + if (!array) + { + array = FromVar(var); + } + return array; + } + + bool JavascriptArray::Jit_TryGetArrayForObjectWithArray(const Var var, bool *const isObjectWithArrayRef, INT_PTR* pVTable, JavascriptArray** pArray) + { + Assert(isObjectWithArrayRef); + Assert(pVTable); + Assert(pArray); + + if (*pVTable == VirtualTableInfo<DynamicObject>::Address || + *pVTable == VirtualTableInfo<CrossSiteObject<DynamicObject>>::Address) + { + ArrayObject* objectArray = DynamicObject::FromVar(var)->GetObjectArray(); + *pArray = (objectArray && Is(objectArray)) ? FromVar(objectArray) : nullptr; + if (!(*pArray)) + { + return false; + } + *isObjectWithArrayRef = true; + *pVTable = VirtualTableInfoBase::GetVirtualTable(*pArray); + } + return true; } JavascriptArray *JavascriptArray::GetArrayForArrayOrObjectWithArray( @@ -664,7 +720,7 @@ using namespace Js; const SparseArraySegmentBase *JavascriptArray::Jit_GetArrayHeadSegmentForArrayOrObjectWithArray(const Var var) { JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Array_Jit_GetArrayHeadSegmentForArrayOrObjectWithArray); - JavascriptArray *const array = GetArrayForArrayOrObjectWithArray(var); + JavascriptArray *const array = Jit_GetArrayForArrayOrObjectWithArray(var); return array ? array->head : nullptr; JIT_HELPER_END(Array_Jit_GetArrayHeadSegmentForArrayOrObjectWithArray); } @@ -701,8 +757,7 @@ using namespace Js; { JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Array_Jit_GetArrayLength); bool isObjectWithArray; - TypeId arrayTypeId; - JavascriptArray *const array = GetArrayForArrayOrObjectWithArray(var, &isObjectWithArray, &arrayTypeId); + JavascriptArray *const array = Jit_GetArrayForArrayOrObjectWithArray(var, &isObjectWithArray); return array && !isObjectWithArray ? array->GetLength() : 0; JIT_HELPER_END(Array_Jit_GetArrayLength); } @@ -717,7 +772,7 @@ using namespace Js; DynamicObjectFlags JavascriptArray::Jit_GetArrayFlagsForArrayOrObjectWithArray(const Var var) { JIT_HELPER_NOT_REENTRANT_NOLOCK_HEADER(Array_Jit_GetArrayFlagsForArrayOrObjectWithArray); - JavascriptArray *const array = GetArrayForArrayOrObjectWithArray(var); + JavascriptArray *const array = Jit_GetArrayForArrayOrObjectWithArray(var); return array && array->UsesObjectArrayOrFlagsAsFlags() ? array->GetFlags() : DynamicObjectFlags::None; JIT_HELPER_END(Array_Jit_GetArrayFlagsForArrayOrObjectWithArray); }
lib/Runtime/Library/JavascriptArray.h+3 −1 modified@@ -439,7 +439,9 @@ namespace Js void LinkSegmentsCommon(SparseArraySegmentBase* prev, SparseArraySegmentBase* current); public: - static JavascriptArray *GetArrayForArrayOrObjectWithArray(const Var var); + static JavascriptArray *Jit_GetArrayForArrayOrObjectWithArray(const Var var); + static JavascriptArray *Jit_GetArrayForArrayOrObjectWithArray(const Var var, bool *const isObjectWithArrayRef); + static bool Jit_TryGetArrayForObjectWithArray(const Var var, bool *const isObjectWithArrayRef, INT_PTR* vtable, JavascriptArray ** array); static JavascriptArray *GetArrayForArrayOrObjectWithArray(const Var var, bool *const isObjectWithArrayRef, TypeId *const arrayTypeIdRef); static const SparseArraySegmentBase *Jit_GetArrayHeadSegmentForArrayOrObjectWithArray(const Var var); static uint32 Jit_GetArrayHeadSegmentLength(const SparseArraySegmentBase *const headSegment);
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- www.exploit-db.com/exploits/45571/mitreexploitx_refsource_EXPLOIT-DB
- github.com/advisories/GHSA-4c93-q79v-mw45ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-8466ghsaADVISORY
- www.securityfocus.com/bid/105243mitrevdb-entryx_refsource_BID
- www.securitytracker.com/id/1041623mitrevdb-entryx_refsource_SECTRACK
- github.com/chakra-core/ChakraCore/commit/a404dec6506962d9a608ca9642b0aab147a0f8d1ghsaWEB
- github.com/chakra-core/ChakraCore/pull/5688ghsaWEB
- portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8466ghsax_refsource_CONFIRMWEB
- web.archive.org/web/20210516130455/http://www.securityfocus.com/bid/105243ghsaWEB
- web.archive.org/web/20210517133345/http://www.securitytracker.com/id/1041623ghsaWEB
- www.exploit-db.com/exploits/45571ghsaWEB
News mentions
0No linked articles in our index yet.