CVE-2023-4761 - Out of Bounds Memory Access in FedCM in Google Chrome – What Happened, How It Works, and How Attackers Could Exploit It
In August 2023, Google patched a high-severity vulnerability in Chrome known as CVE-2023-4761. This flaw affected Chrome’s FedCM (Federated Credential Management) component, and more specifically, allowed attackers who had already compromised the renderer process to read memory they shouldn’t be able to, using just a specially crafted HTML page.
This long read explains, in straightforward language, how the vulnerability worked, how it could be exploited, and what the real-world consequences might be. For developers and IT professionals, I’ll include code snippets and links to official references. Let’s explore the risk and see what you can learn from this Chrome security story.
What is CVE-2023-4761?
Type: Out of bounds memory read in Chrome’s FedCM
Severity: High (Chromium advisory)
Affected: Chrome versions before 116..5845.179
Fixed: August 2023
Why is FedCM Important?
FedCM is designed to help manage federated logins – “Sign in with Google,” etc – *inside* the browser, providing privacy and avoiding tracking. Unfortunately, a bug in FedCM allowed a renderer process (the one responsible for the web page content) to read memory out of bounds. If an attacker can get code running in the renderer (by exploiting a separate bug or through a malicious extension), they could use CVE-2023-4761 to gain access to memory belonging to other parts of the process, possibly exposing private or sensitive data.
Technical Details: What Actually Went Wrong?
In a nutshell: The bug comes from *out of bounds memory access* in C++ code inside the FedCM implementation.
What is Out of Bounds Memory Access?
This is when code tries to read (or write) outside the boundaries of an array or buffer. It’s a classic source of vulnerabilities in C and C++ programs. Often, this lets attackers leak sensitive data from memory—sometimes even causing the program to crash or behave unpredictably.
Here’s a simplified example in plain C++ (not Chrome’s actual code)
void handleTokens(std::vector<Token> tokens) {
for (size_t i = ; i <= tokens.size(); ++i) { // Bug! Should be <
processToken(tokens[i]);
}
}
In the above code, i <= tokens.size() goes *one step too far*, accessing out-of-bounds memory during the last loop.
In Chrome’s FedCM
The Chromium bug tracker is restricted (not public for this issue for obvious security reasons), but the summary tells us:
> Out of bounds memory read in FedCM in Google Chrome prior to 116..5845.179
An attacker could *abuse* this out-of-bounds read by manipulating FedCM through complex crafted HTML and JavaScript running in a compromised renderer process. For instance, feeding Federated Credential Management APIs with malicious or unexpected input.
Step-By-Step Exploit Scenario
1. Initial Compromise – The attacker gets code running in a Chrome renderer process. This usually means exploiting another vulnerability, or tricking a user into installing a malicious extension.
2. Trigger the Bug – The attacker serves malicious HTML/JavaScript utilizing FedCM APIs in unexpected ways (e.g., unusual parameters, huge tokens).
3. Out-of-Bounds Read – Chrome incorrectly reads memory past the end of its intended buffer, potentially leaking:
Other site’s cookies or tokens (in rare cases)
- Heap/stack addresses (useful for further attacks)
4. Data Exfiltration – The attacker sends the leaked data back to a server, or uses the information to escalate their privileges or chain attacks.
Real-World Risk
- Renderer sandboxing: Chrome’s renderer is supposed to be isolated, but leaking sensitive info could help attackers break out or gather data for more serious attacks.
- Chaining bugs: Memory disclosure bugs like this are gold for attackers, because they make it easier to exploit even more serious vulnerabilities (like remote code execution).
Simple Exploit Pseudocode
While the actual exploitation details (and Chrome’s code) are not public, here’s a demonstrative pseudocode of what a crafted HTML/JS attack might look like:
// (Pseudo) JavaScript that triggers FedCM in an unusual way
async function leakMemory() {
const hugeTokenList = new Array(10000).fill("A".repeat(4096));
try {
await navigator.credentials.get({
federated: {
providers: ["https://accounts.google.com";],
tokens: hugeTokenList // Abnormally long token array
}
});
} catch (e) {
// In a real exploit, examine the error and page memory for leakage
console.log('Potential leakage:', e);
}
}
leakMemory();
*Note: This code won’t leak actual memory in patched Chrome, but with the CVE-2023-4761 bug present, such input could trigger an out-of-bounds read in the browser process, and the response/error might contain parts of out-of-bounds memory if not filtered correctly.*
How Was It Fixed?
According to the Chrome release notes, the issue was fixed in:
Chrome 116..5845.179 (Stable channel)
Google pushed out updates for Windows, Mac, and Linux. The patch most likely involved fixing the boundary check to prevent reading past the end of internal FedCM data structures.
Update Chrome! Make sure your browser is running 116..5845.179 or later.
- Be cautious with browser extensions and unfamiliar pages, as renderer bugs often require that initial compromise.
- Developers: Always use safe iterators and bounds-checking in C/C++, and fuzz your APIs for odd edge cases.
More Information
- Google Chrome Release Notes (August 2023)
- NVD entry for CVE-2023-4761
- FedCM API on MDN
- Chromium security bug tracking (restricted, but status can be checked)
Conclusion
CVE-2023-4761 is a classic example of how even “read only” memory bugs in complex browser features can open the door to privacy and security risks. Modern browsers are good at isolating untrusted code, but every time a boundary check is missed in C++, there is a potential for attackers to peek behind the curtains. Keep your browser up to date and, if you’re a developer, keep learning from stories like this to avoid similar bugs and keep users safe!
Timeline
Published on: 09/05/2023 22:15:00 UTC
Last modified on: 09/08/2023 15:45:00 UTC