Samuel Groß, Project Zero (Originally posted on Project Zero blog 2020-07-27)

The Basics

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

Issue/Bug Report:

Patch CL:

Bug-Introducing CL: Unknown

Reporter(s): Independently, Samuel Groß of Google Project Zero and Coinbase Security

The Code


Exploit sample: N/A

Did you have access to the exploit sample when doing the analysis? Yes, provided by Coinbase Security

The Vulnerability

Bug class: Incorrect Speculation Guards in JIT

Vulnerability details:

See 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:

Incorrect side-effect modelling bugs in JIT compilers date back at least to early 2018, likely even earlier. They have been found multiple times in all popular engines such as JavaScriptCore, V8, and Spidermonkey. In 2019, before this bug was exploited in-the-wild, another incorrect side effect modelling bug (CVE-2019-9810) was used against Firefox at pwn2own.

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.

The Exploit

Is the exploit method known? Yes

Exploit method:

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

Variant analysis

Areas/approach for variant analysis (and why): Auditing side-effect modelling in JIT Compilers

Found variants:

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.

Structural improvements

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 which found a non-security variant of this bug pattern:

0-day detection methods

N/A - Likely hard to detect generically

Other References

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