chakra-core / ChakraCore

ChakraCore is an open source Javascript engine with a C API.
MIT License
9.06k stars 1.19k forks source link

Fixing CVE-2021-42279: Chakra Scripting Engine Memory Corruption Vulnerability #6996

Open bhmohanr-techie opened 3 days ago

bhmohanr-techie commented 3 days ago

Changes For

CVE-2021-42279: Chakra Scripting Engine Memory Corruption Vulnerability. CVE-2021-42279 is a high-severity memory corruption vulnerability affecting the Chakra Scripting Engine and ChakraCore.

The vulnerability stems from an out-of-bounds write, which can potentially be exploited to achieve remote code execution (RCE). An attacker could exploit this by convincing a user to perform certain actions, leading to memory corruption and potentially allowing the attacker to execute arbitrary code on the affected system.

Vulnerability Type

Memory Violation, resulting in Remote Code Execution (RCE)

Affected Versions

All versions of ChakraCore up to and including 1.11.24.

Severity

CVSS Score: 7.5 (HIGH)

Root Cause

Fix

Unit Testing

All unit test cases are executed and there is no failure due to these new changes. In fact, this fix takes effect only when the switch “--ValidateArrayBounds" is passed to the ChakraCore engine, so there is no impact to existing testcases/functionalities.

Sample Output

References

bhmohanr-techie commented 2 days ago

Hi Petr Penzin (@ppenzin )

I hope this message finds you well. I have submitted this pull request (https://github.com/chakra-core/ChakraCore/pull/6996) for ChakraCore that addresses the vulnerability: "CVE-2021-42279 - Chakra Scripting Engine Memory Corruption Vulnerability".

Could you please take some time to review it when you have a chance? I would appreciate any feedback or suggestions you may have.

Thank you for your time and for maintaining ChakraCore. I look forward to your feedback.

ppenzin commented 1 day ago

JavaScript arrays (unlike C or Java arrays) allow writing to arbitrary indices, which then get allocated. Think of JS array indices as properties (fields in other languages) that have numeric names, with the whole object dynamically resizable.

To check whether or not you are observing a memory corruption tools like valgrind can be handy.

Since this vulnerability is reported against Microsoft's NuGet package and not this repo directly I don't have much insight into reproducing it further, also report seems to be only affecting older versions of Windows, which I suspect would be only triggered by an older version of ChakraCore that was used there (which also had additional proprietary API layer).

bhmohanr-techie commented 1 day ago

Thank you very much for your thoughts, Petr Penzin (@ppenzin).

Below are my comments, please correct me if I'm wrong anywhere. (apologies for this lengthier comment, but I want to provide complete information based on which I have come-up with this fix)

An out-of-bounds array write occurs when a program writes data to a memory location outside the bounds of the allocated memory for an array.

In the context of ChakraCore, an out-of-bounds write can lead to memory corruption in the following ways:

1. Overwrite Adjacent Memory: When data is written outside the bounds of an array, it can overwrite adjacent memory regions that may be used for other variables, objects, or control structures. This unintended overwrite can corrupt data, causing unpredictable behavior or program crashes.

2. Corrupt Control Structures: If the out-of-bounds write affects control structures such as function pointers, return addresses, or vtable pointers, it can alter the program's control flow. This can be exploited to execute arbitrary code, leading to potential security vulnerabilities like remote code execution.

3. Heap Corruption: Writing beyond the bounds of a heap-allocated array can corrupt the heap metadata. This can cause heap management functions (e.g., ‘malloc’, ‘free’) to behave incorrectly, potentially leading to further memory corruption, crashes, or exploitable conditions.

4. Stack Corruption: An out-of-bounds write on the stack can overwrite the return address or local variables of a function. This can result in a stack-based buffer overflow, allowing attackers to redirect the execution flow and execute arbitrary code.

In ChakraCore, an out-of-bounds write typically arises from improper handling of JavaScript arrays or typed arrays. Here’s a more detailed look at how this can happen:

1. JavaScript Arrays: JavaScript arrays in ChakraCore are dynamic and can grow as needed. However, if the engine improperly calculates the bounds of the array and allows an out-of-bounds write, it can overwrite other memory regions.

2. Typed Arrays: Typed arrays provide a way to handle binary data directly. They have fixed sizes and are backed by raw memory buffers. If ChakraCore allows an out-of-bounds access to these buffers, it can lead to memory corruption.

Example Scenario Consider a simplified scenario where ChakraCore mishandles the bounds of an array:

// JavaScript code that might trigger out-of-bounds write let arr = new Array(1); arr[100] = 42; // This could lead to out-of-bounds write if not properly handled

If ChakraCore does not correctly check the bounds before writing to the ‘arr[100]’ position, it could write the value ‘42’ to a memory location outside the allocated space for ‘arr’. This could overwrite important data or control structures, leading to memory corruption.

About the Fix:

To address this issue, fix is added to allow setting elements only if the index falls within the bounds of the array. And as I mentioned in my PR commit message, we have ensured two things

  1. We are not breaking existing functionality of ChakraCore
  2. We added a command-line switch, which can be used by users of ChakraCore who need this behavior of writing outside the bounds of an array.

So, none of the exiting functionalities of ChakraCore is affected by this change.

Please let me know if you have any thoughts on my analysis and fix above, and also if you can consider merging the change (please note, this change can help users like me who are still using older version of ChakraCore to take advantage of the fix for the vulnerability)

Thank-you again for your thoughts and suggestions !!!

ppenzin commented 1 day ago

Can you please provide a test that exhibits an out-of-bounds read or write that can be detected via valgrind or similar tool?