VYPR
High severityNVD Advisory· Published Apr 12, 2018· Updated Aug 5, 2024

CVE-2018-0990

CVE-2018-0990

Description

Remote code execution in Chakra scripting engine via memory corruption when handling objects; affects Microsoft Edge and ChakraCore.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Remote code execution in Chakra scripting engine via memory corruption when handling objects; affects Microsoft Edge and ChakraCore.

Vulnerability

A remote code execution vulnerability exists in the way the Chakra scripting engine handles objects in memory in Microsoft Edge, also affecting the open-source ChakraCore engine. The issue is a memory corruption vulnerability, specifically a use-after-free condition in DictionaryTypeHandlerBase::SetPropertyWithDescriptor when processing property descriptors [1][2]. This affects all supported versions of Microsoft Edge (on Windows 10, Windows Server 2016, etc.) and ChakraCore prior to the fix committed on April 10, 2018 [2][3].

Exploitation

An attacker can exploit this vulnerability by hosting a specially crafted website (or leveraging a compromised site that serves attacker-controlled content) and persuading a user to visit it in Microsoft Edge. The user interaction required is simply browsing to the malicious page; no additional privileges are needed. Upon rendering the page, the Chakra engine triggers the memory corruption through a sequence of property set operations, leading to a use-after-free that can be leveraged for code execution [2][3].

Impact

Successful exploitation allows an attacker to execute arbitrary code in the context of the current user. If the user is logged on with 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. The impact is remote code execution with the same privileges as the user [1][3].

Mitigation

Microsoft released security updates for Microsoft Edge as part of the April 2018 Patch Tuesday (MSRC bulletin). For ChakraCore, the fix was committed in commit 91dc6f8599979f2beba46e329be70f0788fa0889 [2]. Users should apply the latest Windows updates or update ChakraCore to a version containing the fix. ChakraCore 1.11 reached end of support on March 9, 2021 [4]; users on unsupported versions should upgrade or migrate to a maintained fork. No reliable workarounds exist for unpatched systems.

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.8.31.8.3

Affected products

3

Patches

1
91dc6f859997

[CVE-2018-0990] Edge - UAF leads to potential RCE in latest version - Qihoo 360

https://github.com/chakra-core/ChakraCoreMatthew McGovernApr 4, 2018via ghsa
2 files changed · +36 21
  • lib/Runtime/Types/DictionaryTypeHandler.cpp+35 20 modified
    @@ -716,9 +716,14 @@ namespace Js
     
         template <typename T>
         template <bool allowLetConstGlobal>
    -    void DictionaryTypeHandlerBase<T>::SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor<T> * descriptor,
    +    void DictionaryTypeHandlerBase<T>::SetPropertyWithDescriptor(DynamicObject* instance,
    +        PropertyRecord const* propertyRecord,
    +        DictionaryPropertyDescriptor<T> ** pdescriptor,
             Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
         {
    +        Assert(pdescriptor && *pdescriptor);
    +        DictionaryPropertyDescriptor<T> * descriptor = *pdescriptor;
    +        PropertyId propertyId = propertyRecord->GetPropertyId();
             Assert(instance);
             Assert((descriptor->Attributes & PropertyDeleted) == 0 || (allowLetConstGlobal && descriptor->IsShadowed));
     
    @@ -784,14 +789,23 @@ namespace Js
     
                 // Wait for the setter to return before setting up the inline cache info, as the setter may change
                 // the attributes
    -            T dataSlot = descriptor->template GetDataPropertyIndex<false>();
    -            if (dataSlot != NoSlots)
    +
    +            if (propertyMap->TryGetReference(propertyRecord, pdescriptor))
                 {
    -                SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
    +                descriptor = *pdescriptor;
    +                T dataSlot = descriptor->template GetDataPropertyIndex<false>();
    +                if (dataSlot != NoSlots)
    +                {
    +                    SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
    +                }
    +                else if (descriptor->GetSetterPropertyIndex() != NoSlots)
    +                {
    +                    SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
    +                }
                 }
    -            else if (descriptor->GetSetterPropertyIndex() != NoSlots)
    +            else
                 {
    -                SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
    +                *pdescriptor = nullptr;
                 }
             }
             SetPropertyUpdateSideEffect(instance, propertyId, value, SideEffects_Any);
    @@ -854,7 +868,7 @@ namespace Js
                 {
                     descriptor->ConvertToData();
                 }
    -            SetPropertyWithDescriptor<allowLetConstGlobal>(instance, propertyId, descriptor, value, flags, info);
    +            SetPropertyWithDescriptor<allowLetConstGlobal>(instance, propertyRecord, &descriptor, value, flags, info);
                 return true;
             }
     
    @@ -1895,25 +1909,26 @@ namespace Js
     
                 if (attributes & PropertyLetConstGlobal)
                 {
    -                SetPropertyWithDescriptor<true>(instance, propertyId, descriptor, value, flags, info);
    +                SetPropertyWithDescriptor<true>(instance, propertyRecord, &descriptor, value, flags, info);
                 }
                 else
                 {
    -                SetPropertyWithDescriptor<false>(instance, propertyId, descriptor, value, flags, info);
    +                SetPropertyWithDescriptor<false>(instance, propertyRecord, &descriptor, value, flags, info);
                 }
    -
    -            if (descriptor->Attributes & PropertyEnumerable)
    +            if (descriptor != nullptr)  //descriptor can dissappear, so this reference may not exist.
                 {
    -                instance->SetHasNoEnumerableProperties(false);
    -            }
    -
    -            if (!(descriptor->Attributes & PropertyWritable))
    -            {
    -                this->ClearHasOnlyWritableDataProperties();
    -                if(GetFlags() & IsPrototypeFlag)
    +                if (descriptor->Attributes & PropertyEnumerable)
                     {
    -                    scriptContext->InvalidateStoreFieldCaches(propertyId);
    -                    instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties();
    +                    instance->SetHasNoEnumerableProperties(false);
    +                }
    +                if (!(descriptor->Attributes & PropertyWritable))
    +                {
    +                    this->ClearHasOnlyWritableDataProperties();
    +                    if (GetFlags() & IsPrototypeFlag)
    +                    {
    +                        scriptContext->InvalidateStoreFieldCaches(propertyId);
    +                        instance->GetLibrary()->NoPrototypeChainsAreEnsuredToHaveOnlyWritableDataProperties();
    +                    }
                     }
                 }
     
    
  • lib/Runtime/Types/DictionaryTypeHandler.h+1 1 modified
    @@ -247,7 +247,7 @@ namespace Js
             template<bool allowLetConstGlobal>
             inline DescriptorFlags GetSetterFromDescriptor(DynamicObject* instance, DictionaryPropertyDescriptor<T> * descriptor, Var* setterValue, PropertyValueInfo* info);
             template <bool allowLetConstGlobal>
    -        inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyId propertyId, DictionaryPropertyDescriptor<T> * descriptor,
    +        inline void SetPropertyWithDescriptor(DynamicObject* instance, PropertyRecord const* propertyRecord, DictionaryPropertyDescriptor<T> ** pdescriptor,
                 Var value, PropertyOperationFlags flags, PropertyValueInfo* info);
     
         protected:
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.