MemGC: A Retrospective on a Bygone Frontline of Browser Security

Looking back at my time on the Chakra and the OG Edge team, few projects I had the opportunity to work on feel as consequential to my development as an engineer as my opportunity to work on MemGC (Memory Garbage Collection). In the 2014-16 time period the largest amount of security bugs filed against Internet Explorer were Use-After-Frees (UAFs).
MemGC was our architectural response: a garbage collector designed not just for performance, but as a hard security boundary. It was good enough that it recieved praise from Google project zero: "MemGC is an example of a useful mitigation that results in a clear positive real-world impact". I do love quoting this 😂.
The Core Idea: Turning UAF into a GC Problem
Before MemGC, we tried mitigations like Isolated Heap and Delay Free. They were clever "band-aids" that made exploitation harder but didn't solve the root cause. If a developer forgot to null a pointer after a free(), the door remained open.
MemGC changed the game by bringing the Concurrent Mark-Sweep (CMS) algorithm from the JavaScript engine (Chakra) into the heart of the DOM. We essentially built a safety net:
- Reference-based Lifetime: Instead of manual
free()calls, objects were only reclaimed when the GC could prove no references to them remained. - The Conservative Scan: We treated the stack and registers conservatively. If a value looked like a pointer to a MemGC object, we kept that object alive. This effectively killed "immediate" UAF exploits.
What it Was Good At: Structural Defenses
From a developer’s perspective, MemGC was incredibly successful at "Vulnerability Class Elimination."
- Automation of Safety: It removed the cognitive load from DOM developers. The GC handled the cleanup of complex DOM nodes automatically.
- Performance Balance: By using a concurrent mark-sweep, we kept the UI thread responsive while the GC did the heavy lifting on a background thread.
- Heap Integrity: The data structures we used, like the
HeapBlock32Map, allowed us to quickly determine if an address was a valid object start, preventing many "middle-of-object" pointer tricks.
Where it Failed: The "Blind Spots"
No mitigation is perfect. As developers, we had to confront the reality that hackers are just as creative as we are. One of the most interesting "failures" was a limitation in visibility between different engine components.
As detailed in the "Seeing Double" research, we discovered that having separate "Chakra" and "DOM" heaps created a blind spot. The Chakra recycler didn't always have visibility into allocations on the DOM heap, and vice versa. If a pointer to a Chakra object was stored in a buffer on the DOM heap, the Chakra GC might not "see" it, leading to a UAF despite the protection.
Furthermore, killing UAF simply pushed attackers toward Type Confusion. MemGC ensured the memory was there, but it couldn't ensure the memory was being interpreted as the correct type.
Lessons for Today’s Developers
If I were building a new engine today, what would I take from the MemGC era?
- Defense in Depth: MemGC works best when paired with modern mitigations like Control Flow Guard (CFG).
- The Precision Problem: Conservative scanning prevents UAF but can cause memory leaks. Precise GC is the gold standard for modern systems.
- Language Safety: MemGC was a heroic effort to make C++ safe. Today, we should look toward Rust for compile-time safety guarantees.
Final Thoughts
MemGC was a milestone in browser security. It forced attackers to abandon their favorite exploits and move into much more difficult territory. For those of us who built it, it remains a proud example of weaponizing computer science for defense.
References:
- MSRC: Triaging Exploitability in the MemGC Era
- ZDI: Seeing Double - Exploiting a Blind Spot in MemGC
First published 4/24/26 on blog.farzon.org



