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

CVE-2017-0235

CVE-2017-0235

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-0236, 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 JavaScript engine allows remote code execution via a specially crafted website.

Vulnerability

A remote code execution vulnerability exists in Microsoft Edge in the way that the Chakra JavaScript engine handles objects in memory [1][2]. The vulnerability is a scripting engine memory corruption issue, related to improper handling of JavascriptPromise::AsyncSpawnStep method invocations [3][4]. The vulnerable versions include Microsoft Edge on all versions of Windows 10 (32-bit and x64-based systems) prior to the security update released on May 9, 2017 [2]. The underlying code flaw involves insufficient type checking where the engine assumed resolve and reject parameters were JavascriptFunction objects, but could accept arbitrary values, leading to type confusion and potential memory corruption [3].

Exploitation

An attacker can exploit this vulnerability by hosting a specially crafted website that, when visited by a user using an affected version of Microsoft Edge, triggers the memory corruption [1]. The user must be convinced to browse to the malicious site, typically via a link in an email or instant message [1]. The attacker does not require any special authentication or network position beyond the ability to host a web page and entice a user to visit it.

Impact

Successful exploitation allows the attacker to execute arbitrary code in the context of the current user [1]. If the current user is logged on with administrative privileges, the attacker could gain complete control of the affected system, including the ability to install programs, view, change, or delete data, or create new accounts with full user rights [1].

Mitigation

Microsoft released a security update on May 9, 2017 as part of the May 2017 Patch Tuesday, which addresses this vulnerability [1][2]. The fix can be obtained through Windows Update or the Microsoft Update Catalog. The fix in ChakraCore includes tightening type checks in the AsyncSpawnStep function to ensure that resolve and reject are callable rather than assuming they are JavascriptFunction objects [3][4]. No other workarounds have been published, and users are strongly advised to apply the update promptly.

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 Version 1703 for 32-bit Systems and Windows 10 Version 1703 for x64-based Systems.

Patches

1
f022afb8246a

[CVE-2017-0224, CVE-2017-0235] Chakra - JavascriptPromise::AsyncSpawnStep method invocation issue

https://github.com/chakra-core/ChakraCoreAneesh DivakarakurupMay 9, 2017via ghsa
6 files changed · +78 22
  • lib/Runtime/Library/JavascriptLibrary.cpp+1 1 modified
    @@ -6184,7 +6184,7 @@ namespace Js
             return function;
         }
     
    -    JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* JavascriptLibrary::CreatePromiseAsyncSpawnStepArgumentExecutorFunction(JavascriptMethod entryPoint, JavascriptGenerator* generator, Var argument, JavascriptFunction* resolve, JavascriptFunction* reject, bool isReject)
    +    JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* JavascriptLibrary::CreatePromiseAsyncSpawnStepArgumentExecutorFunction(JavascriptMethod entryPoint, JavascriptGenerator* generator, Var argument, Var resolve, Var reject, bool isReject)
         {
             FunctionInfo* functionInfo = RecyclerNew(this->GetRecycler(), FunctionInfo, entryPoint);
             DynamicType* type = CreateDeferredPrototypeFunctionType(this->inDispatchProfileMode ? ProfileEntryThunk : entryPoint);
    
  • lib/Runtime/Library/JavascriptLibrary.h+1 1 modified
    @@ -984,7 +984,7 @@ namespace Js
             JavascriptExternalFunction* CreateStdCallExternalFunction(StdCallJavascriptMethod entryPointer, PropertyId nameId, void *callbackState);
             JavascriptExternalFunction* CreateStdCallExternalFunction(StdCallJavascriptMethod entryPointer, Var nameId, void *callbackState);
             JavascriptPromiseAsyncSpawnExecutorFunction* CreatePromiseAsyncSpawnExecutorFunction(JavascriptMethod entryPoint, JavascriptGenerator* generator, Var target);
    -        JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* CreatePromiseAsyncSpawnStepArgumentExecutorFunction(JavascriptMethod entryPoint, JavascriptGenerator* generator, Var argument, JavascriptFunction* resolve = NULL, JavascriptFunction* reject = NULL, bool isReject = false);
    +        JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* CreatePromiseAsyncSpawnStepArgumentExecutorFunction(JavascriptMethod entryPoint, JavascriptGenerator* generator, Var argument, Var resolve = nullptr, Var reject = nullptr, bool isReject = false);
             JavascriptPromiseCapabilitiesExecutorFunction* CreatePromiseCapabilitiesExecutorFunction(JavascriptMethod entryPoint, JavascriptPromiseCapability* capability);
             JavascriptPromiseResolveOrRejectFunction* CreatePromiseResolveOrRejectFunction(JavascriptMethod entryPoint, JavascriptPromise* promise, bool isReject, JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper* alreadyResolvedRecord);
             JavascriptPromiseReactionTaskFunction* CreatePromiseReactionTaskFunction(JavascriptMethod entryPoint, JavascriptPromiseReaction* reaction, Var argument);
    
  • lib/Runtime/Library/JavascriptPromise.cpp+27 14 modified
    @@ -1009,8 +1009,8 @@ namespace Js
             JavascriptGenerator* gen = asyncSpawnExecutorFunction->GetGenerator();
             JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* nextFunction = library->CreatePromiseAsyncSpawnStepArgumentExecutorFunction(EntryJavascriptPromiseAsyncSpawnStepNextExecutorFunction, gen, varCallArgs);
     
    -        Assert(JavascriptFunction::Is(resolve) && JavascriptFunction::Is(reject));
    -        AsyncSpawnStep(nextFunction, gen, JavascriptFunction::FromVar(resolve), JavascriptFunction::FromVar(reject));
    +        Assert(JavascriptConversion::IsCallable(resolve) && JavascriptConversion::IsCallable(reject));
    +        AsyncSpawnStep(nextFunction, gen, resolve, reject);
     
             return undefinedVar;
         }
    @@ -1054,8 +1054,8 @@ namespace Js
             JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* asyncSpawnStepExecutorFunction = JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::FromVar(function);
             JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* functionArg;
             JavascriptGenerator* gen = asyncSpawnStepExecutorFunction->GetGenerator();
    -        JavascriptFunction* reject = asyncSpawnStepExecutorFunction->GetReject();
    -        JavascriptFunction* resolve = asyncSpawnStepExecutorFunction->GetResolve();
    +        Var reject = asyncSpawnStepExecutorFunction->GetReject();
    +        Var resolve = asyncSpawnStepExecutorFunction->GetResolve();
     
             if (asyncSpawnStepExecutorFunction->GetIsReject())
             {
    @@ -1071,9 +1071,9 @@ namespace Js
             return undefinedVar;
         }
     
    -    void JavascriptPromise::AsyncSpawnStep(JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* nextFunction, JavascriptGenerator* gen, JavascriptFunction* resolve, JavascriptFunction* reject)
    +    void JavascriptPromise::AsyncSpawnStep(JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* nextFunction, JavascriptGenerator* gen, Var resolve, Var reject)
         {
    -        ScriptContext* scriptContext = resolve->GetScriptContext();
    +        ScriptContext* scriptContext = gen->GetScriptContext();
             JavascriptLibrary* library = scriptContext->GetLibrary();
             Var undefinedVar = library->GetUndefined();
     
    @@ -1105,7 +1105,12 @@ namespace Js
             {
                 // finished with success, resolve the promise
                 value = JavascriptOperators::GetProperty(next, PropertyIds::value, scriptContext);
    -            CALL_FUNCTION(scriptContext->GetThreadContext(), resolve, CallInfo(CallFlags_Value, 2), undefinedVar, value);
    +            if (!JavascriptConversion::IsCallable(resolve))
    +            {
    +                JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedFunction);
    +            }
    +            CALL_FUNCTION(scriptContext->GetThreadContext(), RecyclableObject::FromVar(resolve), CallInfo(CallFlags_Value, 2), undefinedVar, value);
    +
                 return;
             }
     
    @@ -1118,11 +1123,19 @@ namespace Js
             Var promiseVar = CALL_FUNCTION(scriptContext->GetThreadContext(), promiseResolve, CallInfo(CallFlags_Value, 2), library->GetPromiseConstructor(), value);
             JavascriptPromise* promise = FromVar(promiseVar);
     
    -        JavascriptFunction* promiseThen = JavascriptFunction::FromVar(JavascriptOperators::GetProperty(promise, PropertyIds::then, scriptContext));
    -        CALL_FUNCTION(scriptContext->GetThreadContext(), promiseThen, CallInfo(CallFlags_Value, 2), promise, successFunction);
    +        Var promiseThen = JavascriptOperators::GetProperty(promise, PropertyIds::then, scriptContext);
    +        if (!JavascriptConversion::IsCallable(promiseThen))
    +        {
    +            JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedFunction);
    +        }
    +        CALL_FUNCTION(scriptContext->GetThreadContext(), RecyclableObject::FromVar(promiseThen), CallInfo(CallFlags_Value, 2), promise, successFunction);
     
    -        JavascriptFunction* promiseCatch = JavascriptFunction::FromVar(JavascriptOperators::GetProperty(promise, PropertyIds::catch_, scriptContext));
    -        CALL_FUNCTION(scriptContext->GetThreadContext(), promiseCatch, CallInfo(CallFlags_Value, 2), promise, failFunction);
    +        Var promiseCatch = JavascriptOperators::GetProperty(promise, PropertyIds::catch_, scriptContext);
    +        if (!JavascriptConversion::IsCallable(promiseCatch))
    +        {
    +            JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedFunction);
    +        }
    +        CALL_FUNCTION(scriptContext->GetThreadContext(), RecyclableObject::FromVar(promiseCatch), CallInfo(CallFlags_Value, 2), promise, failFunction);
         }
     
     #if ENABLE_TTD
    @@ -1435,7 +1448,7 @@ namespace Js
         }
     #endif
     
    -    JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction(DynamicType* type, FunctionInfo* functionInfo, JavascriptGenerator* generator, Var argument, JavascriptFunction* resolve, JavascriptFunction* reject, bool isReject)
    +    JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction(DynamicType* type, FunctionInfo* functionInfo, JavascriptGenerator* generator, Var argument, Var resolve, Var reject, bool isReject)
             : RuntimeFunction(type, functionInfo), generator(generator), argument(argument), resolve(resolve), reject(reject), isReject(isReject)
         { }
     
    @@ -1464,12 +1477,12 @@ namespace Js
             return this->generator;
         }
     
    -    JavascriptFunction* JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::GetResolve()
    +    Var JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::GetResolve()
         {
             return this->resolve;
         }
     
    -    JavascriptFunction* JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::GetReject()
    +    Var JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction::GetReject()
         {
             return this->reject;
         }
    
  • lib/Runtime/Library/JavascriptPromise.h+6 6 modified
    @@ -78,21 +78,21 @@ namespace Js
             DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction);
     
         public:
    -        JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction(DynamicType* type, FunctionInfo* functionInfo, JavascriptGenerator* generator, Var argument, JavascriptFunction* resolve = NULL, JavascriptFunction* reject = NULL, bool isReject = false);
    +        JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction(DynamicType* type, FunctionInfo* functionInfo, JavascriptGenerator* generator, Var argument, Var resolve = nullptr, Var reject = nullptr, bool isReject = false);
     
             inline static bool Is(Var var);
             inline static JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* FromVar(Var var);
     
             JavascriptGenerator* GetGenerator();
    -        JavascriptFunction* GetReject();
    -        JavascriptFunction* GetResolve();
    +        Var GetReject();
    +        Var GetResolve();
             bool GetIsReject();
             Var GetArgument();
     
         private:
             JavascriptGenerator* generator;
    -        JavascriptFunction* reject;
    -        JavascriptFunction* resolve;
    +        Var reject;
    +        Var resolve;
             bool isReject;
             Var argument;
     
    @@ -466,7 +466,7 @@ namespace Js
             JavascriptPromiseReactionList* rejectReactions;
     
         private :
    -        static void AsyncSpawnStep(JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* nextFunction, JavascriptGenerator* gen, JavascriptFunction* resolve, JavascriptFunction* reject);
    +        static void AsyncSpawnStep(JavascriptPromiseAsyncSpawnStepArgumentExecutorFunction* nextFunction, JavascriptGenerator* gen, Var resolve, Var reject);
     
     #if ENABLE_TTD
         public:
    
  • test/Bugs/bug11026788.js+38 0 added
    @@ -0,0 +1,38 @@
    +//-------------------------------------------------------------------------------------------------------
    +// Copyright (C) Microsoft. All rights reserved.
    +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
    +//-------------------------------------------------------------------------------------------------------
    +
    +async function foo( ) {
    +    var p1 = new Promise(
    +        timeout1 => {
    +            setTimeout( () => {
    +                timeout1( 1 );
    +            }, 500 );
    +        }
    +    );
    +
    +    var p2 = new Promise(
    +        timeout2 => {
    +            setTimeout( () => {
    +                timeout2( 2 );
    +            }, 500 );
    +        }
    +    );
    +
    +    return await p1 + await p2;
    +}
    +
    +promise = foo();
    +promise.__proto__.then = (0x41414141 - 8) >> 0;
    +
    +try {
    +    promise.then( function( value ){} );
    +    WScript.Echo("FAILED");
    +} catch (e) {
    +    if (e instanceof TypeError) {
    +        WScript.Echo("PASSED");
    +    } else {
    +        WScript.Echo("FAILED");
    +    }
    +}
    \ No newline at end of file
    
  • test/Bugs/rlexe.xml+5 0 modified
    @@ -392,4 +392,9 @@
           <compile-flags>-mic:1 -off:simplejit -oopjit- -bgjit-</compile-flags>
         </default>
       </test>
    +  <test>
    +    <default>
    +      <files>bug11026788.js</files>
    +    </default>
    +  </test>
     </regress-exe>
    

Vulnerability mechanics

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

References

7

News mentions

0

No linked articles in our index yet.