Samuel Groß, Project Zero (Originally posted on Project Zero blog 2020-07-27)
Disclosure or Patch Date: 18 June 2019
Product: Mozilla Firefox
Affected Versions: Firefox 67.0.2, likely earlier versions
First Patched Version: Firefox 67.0.3 and Firefox ESR 60.7.1
- Project Zero issue: https://bugs.chromium.org/p/project-zero/issues/detail?id=1820
- Firefox issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1544386
Bug-Introducing CL: Unknown
Reporter(s): Independently, Samuel Groß of Google Project Zero and Coinbase Security
Exploit sample: N/A
Did you have access to the exploit sample when doing the analysis? Yes, provided by Coinbase Security
Bug class: Incorrect Speculation Guards in JIT
See https://bugs.chromium.org/p/project-zero/issues/detail?id=1820 for the full details.
In essence, the JIT failed to ensure that calling
Array.prototype.pop would not end up loading an array element from a prototype of the array. This could then be exploited in different ways:
By storing elements of type T1 in the array and of type T2 in the array’s prototype. In that case, Spidermonkey would assume that the call to
pop() would result in a value of type T1, while at runtime it would result in a value of type T2, thus causing a type confusion. This is how Fuzzilli triggered the bug.
By installing indexed accessors on the prototype. Spidermonkey would assume that the call to
pop() would be side-effect free, which will then not be the case. The result is a classic incorrect side-effect modelling bug, similar to for example CVE-2019-9810 or CVE-2018-17463. This is how the bug was exploited in-the-wild.
Patch analysis: N/A
Thoughts on how this vuln might have been found (fuzzing, code auditing, variant analysis, etc.):
This bug was independently found through fuzzing with Fuzzilli. However, as it is a variant of a popular bug pattern in JIT compilers, it is at least equally likely that it was discovered through manual code analysis.
(Historical/present/future) context of bug:
This vulnerability was chained with CVE-2019-11708, a Firefox sandbox escape according to Coinbase.
According to Objective-See, macOS already included a signature in XProtect that could detect the malware dropped by the exploit. The signature was added by Apple in 2016 without any public disclosure.
Is the exploit method known? Yes
Compiler bug to runtime out-of-bounds array access to type confusion to arbitrary read/write. Similar to other exploits for this type of bug.
The Next Steps
Areas/approach for variant analysis (and why): Auditing side-effect modelling in JIT Compilers
Apart from many earlier variants, Spidermonkey suffered from a similar bug that was fixed in early 2020: CVE-2019-17026 and v8 also fixed a similar vulnerability in early 2020: CVE-2020-6418. Both CVE-2019-17026 and CVE-2020-6418 were also exploited in-the-wild.
One possibility is to help fuzzers detect these kinds of bugs by adding instrumentation that ensures no side-effects happen during execution of operations for which the JIT assumes no side-effects. Mozilla implemented a simple version of this with https://github.com/mozilla/gecko-dev/commit/4ca7a9d3ee9c7fe0d432bd3d3e251238a6f71721 which found a non-security variant of this bug pattern: https://bugzilla.mozilla.org/show_bug.cgi?id=1607670
0-day detection methods
N/A - Likely hard to detect generically
April 2019: Project Zero Issue 1820 June 2019: Twitter thread by Philip Martin of Coinbase Security about detecting the exploit June 2019: Blogpost on the macOS malware dropped by the exploit by Objective-See June 2019: Twitter thread by Samuel Groß on the ITW exploit