In August 2023, Mozilla disclosed CVE-2023-4574, a use-after-free vulnerability affecting Firefox and Thunderbird, specifically relating to the Color Picker window. If you use Firefox before version 117 or Thunderbird before 115.2 (or the ESR equivalents), you could be exposed. Let’s break down how this bug happens, how an attacker might exploit it, and what you should know as a developer or regular user.

Background: How the Color Picker Callback Works

Modern browsers, including Firefox, use Inter-Process Communication (IPC) to securely coordinate between processes. When a web page needs the Color Picker dialog (think: the HTML5 <input type="color"> element), Firefox creates a callback handler over IPC to listen for the result—the color selected by the user.

Normally, there should be only one outstanding callback for a given event. But a logic bug in Firefox and Thunderbird let multiple identical callbacks be created. Due to a mistake in how those callbacks were managed, as soon as one finished, all were destroyed at once—even while the rest might still be running or referenced.

The Vulnerable Code Pattern

Let’s look at a simplified code snippet that shows how this could happen. Please note: This code is not from Firefox itself, but illustrates the general idea.

// Pseudo-code to demonstrate
class ColorPickerCallbackManager {
public:
    std::vector<Callback*> callbacks;

    void AddCallback(Callback* cb) {
        callbacks.push_back(cb);
    }

    void ColorChosen(Color color) {
        for (auto cb : callbacks) {
            cb->Complete(color);
        }
        // Here's the problem: all callbacks destroyed at once.
        callbacks.clear();
    }
};

Suppose Complete() triggers a path that ends up referencing the callback again after callbacks.clear()—this is the use-after-free. In Firefox, the management was more complex, but this is the crux.

Thunderbird < 102.15 & < 115.2

If you’re using any of these, you must update. (See official security advisory)

Exploitation: Turning UAF into a Crash or Code Execution

If malicious JavaScript on a webpage can trigger multiple Color Pickers (e.g., via clever event manipulation, or by exploiting race conditions), and then cause one to finish in a controlled way, it could gain access to a freed object. By spraying the heap (filling memory with attacker-controlled content), they could manipulate what object gets reused in that space, leading to a:

Browser crash (denial of service)

- Potentially, arbitrary code execution if they manage to shape the heap and take over function pointers

Exploit Example (Conceptual, JavaScript)

Here’s pseudo-JavaScript that would be part of a scenario to trigger the bug, though practical attacks would be much more complex:

function triggerColorPickerRace() {
    for (let i = ; i < 10; ++i) {
        let input = document.createElement('input');
        input.type = 'color';
        document.body.appendChild(input);
        // Rapidly fire click events
        input.click();
    }
}
triggerColorPickerRace();

If the browser lets you open multiple color pickers rapidly, each with its own callback, then causing a race between them could hit the bug.

Mitigation & Fix

- Mozilla patched this by ensuring callbacks are tracked and destroyed independently, so one callback finishing doesn’t destroy the rest.
- See patch diff (Requires Bugzilla login for full source)

References

- CVE-2023-4574 NVD Entry
- Mozilla Security Advisory 2023-34
- Thunderbird Security Notes
- Bugzilla report #1844122

Conclusion

This bug is a classic reminder: memory management in complex, multi-threaded (or multi-process) applications is hard. Even a well-tested open-source project can have dangerous use-after-free errors hiding in race conditions. Always keep your browsers and clients updated—and if you write UI code with callbacks or IPC, be extra careful how you track and destroy those objects.

Timeline

Published on: 09/11/2023 09:15:00 UTC
Last modified on: 09/13/2023 11:15:00 UTC