# CVE-2019-1367: Internet Explorer JScript use-after-free

JScript arguments object untracked by GC during Array.sort callback yields use-after-free, exploited in the wild to fake VARs and gain arbitrary read/write in IE.

- Payout: Real-world hack
- Severity: high
- Program: Microsoft Internet Explorer
- Credited: Maddie Stone & Ivan Fratric, Project Zero & Clément Lecigne, Google's Threat Analysis Group (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2020-07-27)
- Disclosed: 2019-09-23
- CVE: CVE-2019-1367
- Write-up quality: 9/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2019/CVE-2019-1367.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2019-1367
- Tags: domain:browser impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:windows technique:chained technique:incomplete-fix technique:source-review vuln:memory-corruption vuln:rce

**Target:** Internet Explorer JScript engine (JScript.dll)
**Root cause:** The arguments object is not tracked by the garbage collector during the Array.sort callback, so a variable assigned into arguments can be freed and later accessed, causing use-after-free of VAR structures.
**Steps:**
1. Load page with `<meta http-equiv="X-UA-Compatible" content="IE=8">` and `<script language="Jscript.Encode">`.
2. Call `[1,2].sort(F)` with custom callback F.
3. In F, allocate 20000 objects into `spray`, then set `arguments[0] = spray[5000]`.
4. Overwrite spray entries and call `CollectGarbage()` to free the VAR block.
5. Access `arguments[0]` — dangling reference to freed VAR (UAF).
**How found:** Variant analysis: actor previously exploited CVE-2018-8653 (UAF in isPrototypeOf callback where `this` untracked by GC), so likely searched for other JScript callbacks where variables/arguments escape GC tracking. Project Zero's own variant hunt manually freed function arguments in every known JScript callback and ran a modified JScript.dll fuzzer that crashes on freed VAR access and never reallocates freed VARs.
**Exploitation:** Free VAR structures (allocated in blocks of 100), reclaim freed memory with a controllable object property name to fake JScript variables, then construct a fake RegExp object: overwrite regexp.code with custom bytecode for write-what-where and use regexp.source (unused bSTR) for arbitrary read. Same exploit reused to escape the browser sandbox via the privileged WPAD service.
**Escalation:** Chained browser RCE with a sandbox escape via WPAD service running as privileged process; same actor reused the bug class across CVE-2018-8653, CVE-2019-1429, CVE-2020-0674.
**Insight:** When a GC bug class is found in one callback (e.g. isPrototypeOf), enumerate every other engine callback that receives arguments/this and test whether those references survive CollectGarbage; instrument the allocator to poison freed VARs and disable reuse to turn silent UAFs into crashes.
