CVE-2019-0806
Description
A remote code execution vulnerability in Microsoft Edge's Chakra scripting engine due to memory corruption, potentially allowing an attacker to gain the same user rights as the current user.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A remote code execution vulnerability in Microsoft Edge's Chakra scripting engine due to memory corruption, potentially allowing an attacker to gain the same user rights as the current user.
Vulnerability
Analysis
CVE-2019-0806 is a remote code execution vulnerability in the Chakra scripting engine used by Microsoft Edge, caused by improper handling of objects in memory. The official description categorizes it as a 'Chakra Scripting Engine Memory Corruption Vulnerability' [1]. The root cause is a type confusion issue in the JIT compiler, where the engine fails to properly invalidate prototype caches when storing fields, allowing an attacker to corrupt memory [3].
Exploitation
To exploit this vulnerability, an attacker would need to host a specially crafted website (or leverage a compromised site that accepts user content) and persuade a user to visit it in Microsoft Edge. No authentication is required, as the attack vector is through a web browser. The vulnerability can be triggered without any user interaction beyond visiting the malicious page [1].
Impact
Successful exploitation could allow an attacker to execute arbitrary code in the context of the current user. If the user has administrative privileges, the attacker could install programs; view, change, or delete data; or create new accounts with full user rights. The vulnerability has a CVSS score indicating high severity [1].
Mitigation
Microsoft released a security update for this vulnerability on April 9, 2019, as part of their monthly Patch Tuesday. Users should ensure Microsoft Edge and Windows are fully updated. The fix addresses the memory corruption by adding checks to invalidate prototype caches when appropriate [3]. ChakraCore, the open-source engine, received a patch in commit 50d1e46aac450f236927b309854e77fce4acd49f [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.11.8 | 1.11.8 |
Affected products
3- Range: unspecified
Patches
150d1e46aac45CVE-2019-0806 Edge - Chakra JIT Type Confusion with
7 files changed · +42 −6
lib/Backend/GlobOptFields.cpp+3 −1 modified@@ -494,7 +494,9 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo case Js::OpCode::NewScObjectNoCtor: if (inGlobOpt) { - KillObjectHeaderInlinedTypeSyms(this->currentBlock, false); + // Opcodes that make an object into a prototype may break object-header-inlining and final type opt. + // Kill all known object layouts. + KillAllObjectTypes(bv); } break;
lib/Backend/JITType.cpp+1 −1 modified@@ -35,7 +35,7 @@ JITType::BuildFromJsType(__in Js::Type * jsType, __out JITType * jitType) Js::DynamicTypeHandler * handler = dynamicType->GetTypeHandler(); data->handler.isObjectHeaderInlinedTypeHandler = handler->IsObjectHeaderInlinedTypeHandler(); - data->handler.isLocked = handler->GetIsLocked(); + data->handler.flags = handler->GetFlags(); data->handler.inlineSlotCapacity = handler->GetInlineSlotCapacity(); data->handler.offsetOfInlineSlots = handler->GetOffsetOfInlineSlots(); data->handler.slotCapacity = handler->GetSlotCapacity();
lib/Backend/JITTypeHandler.cpp+7 −1 modified@@ -19,7 +19,13 @@ JITTypeHandler::IsObjectHeaderInlinedTypeHandler() const bool JITTypeHandler::IsLocked() const { - return m_data.isLocked != FALSE; + return Js::DynamicTypeHandler::GetIsLocked(m_data.flags); +} + +bool +JITTypeHandler::IsPrototype() const +{ + return Js::DynamicTypeHandler::GetIsPrototype(m_data.flags); } uint16
lib/Backend/JITTypeHandler.h+1 −0 modified@@ -12,6 +12,7 @@ class JITTypeHandler bool IsObjectHeaderInlinedTypeHandler() const; bool IsLocked() const; + bool IsPrototype() const; uint16 GetInlineSlotCapacity() const; uint16 GetOffsetOfInlineSlots() const;
lib/Backend/Lower.cpp+23 −0 modified@@ -7353,6 +7353,19 @@ Lowerer::GenerateStFldWithCachedType(IR::Instr *instrStFld, bool* continueAsHelp { Assert(labelTypeCheckFailed == nullptr && labelBothTypeChecksFailed == nullptr); AssertMsg(!instrStFld->HasBailOutInfo(), "Why does a direct field store have bailout?"); + + if (propertySymOpnd->HasInitialType() && propertySymOpnd->HasFinalType()) + { + bool isPrototypeTypeHandler = propertySymOpnd->GetInitialType()->GetTypeHandler()->IsPrototype(); + if (isPrototypeTypeHandler) + { + LoadScriptContext(instrStFld); + m_lowererMD.LoadHelperArgument(instrStFld, IR::IntConstOpnd::New(propertySymOpnd->GetPropertyId(), TyInt32, m_func, true)); + IR::Instr * invalidateCallInstr = IR::Instr::New(Js::OpCode::Call, m_func); + instrStFld->InsertBefore(invalidateCallInstr); + m_lowererMD.ChangeToHelperCall(invalidateCallInstr, IR::HelperInvalidateProtoCaches); + } + } instrStFld->Remove(); return true; } @@ -8177,6 +8190,16 @@ Lowerer::GenerateFieldStoreWithTypeChange(IR::Instr * instrStFld, IR::PropertySy // Now do the store. GenerateDirectFieldStore(instrStFld, propertySymOpnd); + + bool isPrototypeTypeHandler = initialType->GetTypeHandler()->IsPrototype(); + if (isPrototypeTypeHandler) + { + LoadScriptContext(instrStFld); + m_lowererMD.LoadHelperArgument(instrStFld, IR::IntConstOpnd::New(propertySymOpnd->GetPropertyId(), TyInt32, m_func, true)); + IR::Instr * invalidateCallInstr = IR::Instr::New(Js::OpCode::Call, m_func); + instrStFld->InsertBefore(invalidateCallInstr); + m_lowererMD.ChangeToHelperCall(invalidateCallInstr, IR::HelperInvalidateProtoCaches); + } } bool
lib/JITIDL/JITTypes.h+1 −1 modified@@ -90,7 +90,7 @@ typedef IDL_DEF([ref]) PSCRIPTCONTEXT_HANDLE * PPSCRIPTCONTEXT_HANDLE; typedef struct TypeHandlerIDL { IDL_Field(boolean) isObjectHeaderInlinedTypeHandler; - IDL_Field(boolean) isLocked; + IDL_Field(unsigned char) flags; IDL_Field(unsigned short) inlineSlotCapacity; IDL_Field(unsigned short) offsetOfInlineSlots;
lib/Runtime/Types/TypeHandler.h+6 −2 modified@@ -348,13 +348,17 @@ namespace Js (v) Seal (vi) Freeze */ - bool GetIsLocked() const { return (this->flags & IsLockedFlag) != 0; } + bool GetIsLocked() const { return GetIsLocked(this->flags); } + static bool GetIsLocked(byte flags) { return (flags & IsLockedFlag) != 0; } bool GetIsShared() const { return (this->flags & IsSharedFlag) != 0; } bool GetMayBecomeShared() const { return (this->flags & MayBecomeSharedFlag) != 0; } bool GetIsOrMayBecomeShared() const { return (this->flags & (MayBecomeSharedFlag | IsSharedFlag)) != 0; } bool GetHasKnownSlot0() const { return (this->flags & HasKnownSlot0Flag) != 0; } - bool GetIsPrototype() const { return (this->flags & IsPrototypeFlag) != 0; } + + bool GetIsPrototype() const { return GetIsPrototype(this->flags); } + static bool GetIsPrototype(byte flags) { return (flags & IsPrototypeFlag) != 0; } + bool GetIsInlineSlotCapacityLocked() const { return (this->propertyTypes & PropertyTypesInlineSlotCapacityLocked) != 0; } void LockTypeHandler() { Assert(IsLockable()); SetFlags(IsLockedFlag); }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.