-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixing CVE-2021-42279: Chakra Scripting Engine Memory Corruption Vulnerability #6996
Conversation
========= 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: ========= # 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. 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. # 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. Fix: === # To address this issue, fix is added to allow setting elements only if the index falls within the bounds of the array. # This fix is added such that, it takes effect only if additional command line switch “--ValidateArrayBounds” is passed to ChakraCore. With this, we ensure that the existing functionalities of ChakraCore continues to work as before. # Users of ChakraCore can take advantage of the newly added switch “--ValidateArrayBounds", which helps in making sure, any injection of elements to an array is restricted only within the bounds of the array. With this, we ensure that the out-of-bound write issue is not seen, there by preventing write operation to sensitive memory locations. # By default, “--ValidateArrayBounds" will be false. 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: =========== Consider Script "test.js" below: let arr = new Array(2); console.log("arr.length is " + arr.length) arr[0] = 0; console.log("arr[0] is " + arr[0]) arr[1] = 1; console.log("arr[1] is " + arr[1]) arr[100] = 100; console.log("arr[100] is " + arr[100]) Output without the newly added switch, C:\temp>ch.exe test.js arr.length is 2 arr[0] is 0 arr[1] is 1 arr[100] is 100 Output with the newly added switch, C:\temp>ch.exe --ValidateArrayBounds test.js arr.length is 2 arr[0] is 0 arr[1] is 1 RangeError: Memory index is out of range at Global code (C:\temp\test.js:11:1) References: ======== https://nvd.nist.gov/vuln/detail/CVE-2021-42279 https://www.cve.org/CVERecord?id=CVE-2021-42279 https://github.com/chakra-core/ChakraCore
Avoid using MSVC-internal _STRINGIZE chakra-core#6970 Below is the comment from Stephan T. Lavavej in the above mentioned pull request: "I work on Microsoft's C++ Standard Library implementation, where we recently merged microsoft/STL#4405 to remove our internal _STRINGIZE macro. Our "Real World Code" test suite, which builds popular open-source projects like yours, found that you were using this MSVC-internal macro and therefore our change broke your code. The C++ Standard's rule is that _Leading_underscore_capital identifiers (including _LEADING_UNDERSCORE_ALL_CAPS) are reserved for the compiler and Standard Library, so other libraries and applications should avoid using such reserved identifiers. This is N4971 5.10 [lex.name]/3: In addition, some identifiers appearing as a token or preprocessing-token are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required. — Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use. This PR introduces non-reserved names that will work on all platforms."
…es as defined in tools/StyleChecks/check_copyright.py.
Hi Petr Penzin (@ppenzin ) I hope this message finds you well. I have submitted this pull request (#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. |
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). |
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: 2. Corrupt Control Structures: 3. Heap Corruption: 4. Stack Corruption: 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: 2. Typed Arrays: Example Scenario // JavaScript code that might trigger out-of-bounds write 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
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 !!! |
Can you please provide a test that exhibits an out-of-bounds read or write that can be detected via valgrind or similar tool? |
1. I have added two new tests as part of the unit test framework within ChakraCore (one test to verify out-of-bounds access behavior without my fix, and other test with my fix). In both the cases, I have verified that the tests are PASSED. 2. In addition to my earlier commits for handling out-of-bounds write with javascript arrays, I have added a change here to address out-of-bounds read scenario.
…ests... Added a change here to summarize the unit test results, so that the unit test framewokr can capture and report the test results.
Hey @bhmohanr-techie thanks for your work! What @ppenzin meant is that we don’t need to merge this PR because
The scenario you provided runs just fine in any JS engine. let arr = new Array(1);
// arr := [ empty ]
arr[100] = 42;
// arr := [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,42] |
Hi Petr Penzin (@ppenzin ) and Lukas Kurz (@ShortDevelopment ) Greetings!!! As mentioned by you, there is no clear information available on what actually causes this vulnerability. However, the fix attempted in my PR is to handle a possible scenario where out-of-bounds access can lead to this issue. My fix can help users, who strictly want to access elements within the defined array boundary. Also, please refer to my analysis below with multiple tools and let me know your valuable suggestions. Please find below my response for Pete's latest comment on tests/tools to exhibit out-of-bounds array read/write: Valgrind is a programming tool primarily used for memory debugging, memory leak detection, and profiling for programs written in languages like C and C++. However, it does not support JavaScript directly. For JavaScript, there isn't a direct equivalent of Valgrind that can detect out-of-bounds errors. However, there are other tools and methods specifically designed for JavaScript that can help you detect such issues. Below are my findings on the same: When it comes to checking for out-of-bounds errors in JavaScript arrays, the ChakraCore engine, like other JavaScript engines, adheres to the ECMAScript standard which specifies how arrays should behave. JavaScript arrays are designed to handle out-of-bounds access gracefully by returning 'undefined' for non-existent elements. Possible Approaches:However, to explicitly check for out-of-bounds access in your JavaScript code while using ChakraCore, we can use the following approaches: 1. Manual Check function accessArray(arr, index) { 2. Using Proxy let handler = { 3. ChakraCore Debugger Static Analysis ToolsWe could use tools like ESLint, Flow, or TypeScript to catch potential out-of-bounds errors during development. In my fix here, I have tried using ESLint
I have evaluated the behavior with ESLint and Flow tools. Below are the results. 1. ESLint: 2. Flow: Unit Testing: With all the observations above, I could summarize as below:
So Pete, requesting you to kindly share your thoughts on above observations, as well as whether we can consider merging this change for the benefit of affected users. Thank-you once again. |
…g UnitTestFramework... This will be replaced with new unit test soon, that adheres to ChakraCore's unit test framework.
Merging PR: chakra-core#6531. This is the change that was added by Microsoft as part of their December 2020 Security Update, which addresses the CVE-2020-17131. This CVE is to address Out-of-bounds Write in ChakraCore, and there by fixing memory corruption vulnerability. This change is unfortunately missed in the latest ChakraCore code base, and hence adding this for review.
Hi Petr Penzin (@ppenzin ) Greetings!!! Hope you are doing good. After our last discussion, I did further analysis to figure out the fix for the vulnerability CVE-2021-42279. As part of my analysis, I went thru the history of Chakracore, and below are my findings:
I did spend some time, by verifying multiple online resources, and figured out that the December 2020 security update from Microsoft has fix to address "CVE-2020-17131 : Out-of-bounds Write in Chakra, Chakra Scripting Engine Memory Corruption Vulnerability" This fix was added as part of this pull request #6531 on December 8, 2020. When I checked to see if this fix is part of the latest Chakracore code base, I found it missing in both 1.12 and master branches. So, here I'm adding changes to merge the fix added in Microsoft as part of their December 2020 security update. So, in this PR, I have two changes added:
Please review this change and let me know if the changes are looking good and can be considered for merging in the master branch. Thankyou!!! |
Hi Petr Penzin (@ppenzin ) Greetings!!! I hope this message finds you well. Please let me know if you had chance to review my earlier comment. As mentioned in that comment, after doing some research I figured out that the fix added my Microsoft in Dec '2020 windows patch is not merged in Chakrocore. I have merged the PR from Microsoft. So, we have two changes as part of this pull request:
Also, though my change 1 above is safe (enabled if a CLI parameter is passed), if you prefer only merging the PR from microsoft, we can do that as well. Kindly let me know your thoughts here. Thanks. |
If this wasn't claimed to be a security fix I'd probably let it hang around longer. Specific questions were asked by maintainers and sufficient answers were not received. I don't see how unrelated 2020 fix applies here or why it needs to be merged into master. |
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
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. 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.
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.
Fix
In this PR, I have added two changes:
Merging the changes from December 2020 Security Update #6531 which will bring the fix added for CVE-2020-17131, and was made available as part of December 2020 Windows security update
- The December 2020 security update from Microsoft has fix to address "CVE-2020-17131 : Out-of-bounds Write in Chakra, Chakra Scripting Engine Memory Corruption Vulnerability"
- This fix was added as part of this pull request December 2020 Security Update #6531 on December 8, 2020.
- When I checked to see if this fix is part of the latest Chakracore code base, I found it missing in both 1.12 and master branches.
- So, here I'm adding changes to merge the fix added in Microsoft as part of their December 2020 security update.
In addition to merging above mentioned PR, a defensive check is also added to handle out-of-bounds array read/write, as described below:
- To address this issue, fix is added to allow setting elements only if the index falls within the bounds of the array.
- This fix is added such that, it takes effect only if additional command line switch “--ValidateArrayBounds” is passed to ChakraCore. With this, we ensure that the existing functionalities of ChakraCore continues to work as before.
- Users of ChakraCore can take advantage of the newly added switch “--ValidateArrayBounds", which helps in making sure, any injection of elements to an array is restricted only within the bounds of the array. With this, we ensure that the out-of-bound write issue is not seen, there by preventing write operation to sensitive memory locations.
- By default, “--ValidateArrayBounds" will be false.
Unit Testing
Sample Output
Consider Script "test.js" below:
let arr = new Array(2);
console.log("arr.length is " + arr.length)
arr[0] = 0;
console.log("arr[0] is " + arr[0])
arr[1] = 1;
console.log("arr[1] is " + arr[1])
arr[100] = 100;
console.log("arr[100] is " + arr[100])_
Output without the newly added switch,
C:\temp>ch.exe test.js
arr.length is 2
arr[0] is 0
arr[1] is 1
arr[100] is 100
Output with the newly added switch,
C:\temp>ch.exe --ValidateArrayBounds test.js
arr.length is 2
arr[0] is 0
arr[1] is 1
RangeError: Memory index is out of range
at Global code (C:\temp\test.js:11:1)
References