CVE-2017-0028 (published 2017-07-17T13:18Z)

A remote code execution vulnerability exists when Microsoft scripting engine improperly accesses objects in memory. The vulnerability could corrupt memory in a way that enables an attacker to execute arbitrary code in the context of the current user. An attacker who successfully exploited the vulnerability could gain the same user rights as the current user, aka "Scripting Engine Memory Corruption Vulnerability."

Severity: HIGH
CVSS v2 base score: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-119
cwe_name: Improper Restriction of Operations within the Bounds of a Memory Buffer
description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
extended_description: 
            Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced. This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data.
         
         

Fix information:
repo_url: https://github.com/Microsoft/ChakraCore
commit_details: repo_url: https://github.com/Microsoft/ChakraCore
author: Paul Leathers
author_date: 2017-01-12 11:23:32-08:00
msg: [CVE-2017-0028] Fix binding of 'async' identifier in the presence of async arrow function.
repository: repo_url: https://github.com/Microsoft/ChakraCore
repo_name: chakra-core/ChakraCore
description: ChakraCore is an open source Javascript engine with a C API.
repo_language: JavaScript
owner: Microsoft
file_changes: filename: Parse.cpp
change_type: ModificationType.MODIFY
diff: @@ -2863,6 +2863,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
     _Inout_opt_ charcount_t *plastRParen /*= nullptr*/)
 {
     ParseNodePtr pnode = nullptr;
+    PidRefStack *savedTopAsyncRef = nullptr;
     charcount_t ichMin = 0;
     size_t iecpMin = 0;
     size_t iuMin;
@@ -2915,6 +2916,13 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
                 isLambdaExpr = true;
                 goto LFunction;
             }
+            else if (m_token.tk == tkLParen)
+            {
+                // This is potentially an async arrow function. Save the state of the async references
+                // in case it needs to be restored. (Note that the case of a single parameter with no ()'s
+                // is detected upstream and need not be handled here.)
+                savedTopAsyncRef = pid->GetTopRef();
+            }
         }
 
         // Don't push a reference if this is a single lambda parameter, because we'll reparse with
@@ -3269,6 +3277,18 @@ LFunction :
 
     pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, isAsyncExpr, &fCanAssign, &term, pfIsDotOrIndex);
 
+    if (savedTopAsyncRef != nullptr &&
+        this->m_token.tk == tkDArrow)
+    {
+        // This is an async arrow function; we're going to back up and reparse it.
+        // Make sure we don't leave behind a bogus reference to the 'async' identifier.
+        for (IdentPtr pid = wellKnownPropertyPids.async; pid->GetTopRef() != savedTopAsyncRef;)
+        {
+            Assert(pid->GetTopRef() != nullptr);
+            pid->RemovePrevPidRef(nullptr);
+        }
+    }
+
     // Pass back identifier if requested
     if (pToken && term.tk == tkID)
     {

programming_language: C++
filename: lambda-params-shadow.js
change_type: ModificationType.MODIFY
diff: @@ -18,7 +18,14 @@ class B extends A {
     }
 }
 let b = new B();
-if (count !== 3) {
+class async extends A {
+    constructor() {
+        super();
+        let Q = async A => { A };
+    }
+}
+let a = new async();
+if (count !== 4) {
     WScript.Echo('fail');
 }
 

programming_language: TypeScript