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.
| Package | Affected versions | Patched versions |
|---|---|---|
Microsoft.ChakraCoreNuGet | < 1.4.4 | 1.4.4 |
Affected products
4- Microsoft Corporation/Microsoft Edgev5Range: Windows 10 Version 1703 for 32-bit Systems and Windows 10 Version 1703 for x64-based Systems.
Patches
1f022afb8246a[CVE-2017-0224, CVE-2017-0235] Chakra - JavascriptPromise::AsyncSpawnStep method invocation issue
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- portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-0235nvdPatchVendor AdvisoryWEB
- www.securityfocus.com/bid/98230nvdThird Party AdvisoryVDB Entry
- github.com/advisories/GHSA-rm8g-7g54-w6fhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-0235ghsaADVISORY
- github.com/chakra-core/ChakraCore/commit/f022afb8246acc98e74a887bb655ac512caf6e72ghsaWEB
- github.com/chakra-core/ChakraCore/pull/2959ghsaWEB
- web.archive.org/web/20210124044045/http://www.securityfocus.com/bid/98230ghsaWEB
News mentions
0No linked articles in our index yet.