The AI world moves fast, so we’ve been hard at work keeping security apace with recent advancements. One of our approaches, in alignment with Google’s Secure AI Framework (SAIF), is using AI itself to automate and streamline routine and manual security tasks, including fixing security bugs. Last year we wrote about our experiences using LLMs to expand vulnerability testing coverage, and we’re excited to share some updates.
Today, we’re releasing our fuzzing framework as a free, open source resource that researchers and developers can use to improve fuzzing’s bug-finding abilities. We’ll also show you how we’re using AI to speed up the bug patching process. By sharing these experiences, we hope to spark new ideas and drive innovation for a stronger ecosystem security.
Last August, we announced our framework to automate manual aspects of fuzz testing (“fuzzing”) that often hindered open source maintainers from fuzzing their projects effectively. We used LLMs to write project-specific code to boost fuzzing coverage and find more vulnerabilities. Our initial results on a subset of projects in our free OSS-Fuzz service were very promising, with code coverage increased by 30% in one example. Since then, we’ve expanded our experiments to more than 300 OSS-Fuzz C/C++ projects, resulting in significant coverage gains across many of the project codebases. We’ve also improved our prompt generation and build pipelines, which has increased code line coverage by up to 29% in 160 projects.
How does that translate to tangible security improvements? So far, the expanded fuzzing coverage offered by LLM-generated improvements allowed OSS-Fuzz to discover two new vulnerabilities in cJSON and libplist, two widely used projects that had already been fuzzed for years. As always, we reported the vulnerabilities to the project maintainers for patching. Without the completely LLM-generated code, these two vulnerabilities could have remained undiscovered and unfixed indefinitely.
Fuzzing is fantastic for finding bugs, but for security to improve, those bugs also need to be patched. It’s long been an industry-wide struggle to find the engineering hours needed to patch open bugs at the pace that they are uncovered, and triaging and fixing bugs is a significant manual toll on project maintainers. With continued improvements in using LLMs to find more bugs, we need to keep pace in creating similarly automated solutions to help fix those bugs. We recently announced an experiment doing exactly that: building an automated pipeline that intakes vulnerabilities (such as those caught by fuzzing), and prompts LLMs to generate fixes and test them before selecting the best for human review.
This AI-powered patching approach resolved 15% of the targeted bugs, leading to significant time savings for engineers. The potential of this technology should apply to most or all categories throughout the software development process. We’re optimistic that this research marks a promising step towards harnessing AI to help ensure more secure and reliable software.
Since we’ve now open sourced our framework to automate manual aspects of fuzzing, any researcher or developer can experiment with their own prompts to test the effectiveness of fuzz targets generated by LLMs (including Google’s VertexAI or their own fine-tuned models) and measure the results against OSS-Fuzz C/C++ projects. We also hope to encourage research collaborations and to continue seeing other work inspired by our approach, such as Rust fuzz target generation.
If you’re interested in using LLMs to patch bugs, be sure to read our paper on building an AI-powered patching pipeline. You’ll find a summary of our own experiences, some unexpected data about LLM’s abilities to patch different types of bugs, and guidance for building pipelines in your own organizations.
Helping Pixel owners upgrade to the easier, safer way to sign in
Your phone contains a lot of your personal information, from financial data to photos. Pixel phones are designed to help protect you and your data, and make security and privacy as easy as possible. This is why the Pixel team has been especially excited about passkeys—the easier, safer alternative to passwords.
Passkeys are safer because they’re unique to each account, and are more resistant against online attacks such as phishing. They’re easier to use because there’s nothing for you to remember: when it’s time to sign in, using a passkey is as simple as unlocking your device with your face or fingerprint, or your PIN/pattern/password.
Google is working to accelerate passkey adoption. We’ve launched support for passkeys on Google platforms such as Android and Chrome, and recently we announced that we’re making passkeys a default option across personal Google Accounts. We’re also working with our partners across the industry to make passkeys available on more websites and apps.
Recently, we took things a step further. As part of last December’s Pixel Feature Drop, we introduced a new feature to Google Password Manager: passkey upgrades. With this new feature, Google Password Manager will let you discover which of your accounts support passkeys, and help you upgrade with just a few taps.
This new passkey upgrade experience is now available on Pixel phones (starting from Pixel 5a) as well as Pixel Tablet. Google Password manager will incorporate these updates for other platforms in the future.
Welcome back to our latest update on MiraclePtr, our project to protect against use-after-free vulnerabilities in Google Chrome. If you need a refresher, you can read our previous blog post detailing MiraclePtr and its objectives.
We are thrilled to announce that since our last update, we have successfully enabled MiraclePtr for more platforms and processes:
Furthermore, we have changed security guidelines to downgrade MiraclePtr-protected issues by one severity level!
First let’s focus on its security impact. Our analysis is based on two primary information sources: incoming vulnerability reports and crash reports from user devices. Let's take a closer look at each of these sources and how they inform our understanding of MiraclePtr's effectiveness.
Chrome vulnerability reports come from various sources, such as:
For the purposes of this analysis, we focus on vulnerabilities that affect platforms where MiraclePtr was enabled at the time the issues were reported. We also exclude bugs that occur inside a sandboxed renderer process. Since the initial launch of MiraclePtr in 2022, we have received 168 use-after-free reports matching our criteria.
What does the data tell us? MiraclePtr effectively mitigated 57% of these use-after-free vulnerabilities in privileged processes, exceeding our initial estimate of 50%. Reaching this level of effectiveness, however, required additional work. For instance, we not only rewrote class fields to use MiraclePtr, as discussed in the previous post, but also added MiraclePtr support for bound function arguments, such as Unretained pointers. These pointers have been a significant source of use-after-frees in Chrome, and the additional protection allowed us to mitigate 39 more issues.
Unretained
Moreover, these vulnerability reports enable us to pinpoint areas needing improvement. We're actively working on adding support for select third-party libraries that have been a source of use-after-free bugs, as well as developing a more advanced rewriter tool that can handle transformations like converting std::vector<T*> into std::vector<raw_ptr<T>>. We've also made several smaller fixes, such as extending the lifetime of the task state object to cover several issues in the “this pointer” category.
std::vector<T*>
std::vector<raw_ptr<T>>
this
Crash reports offer a different perspective on MiraclePtr's effectiveness. As explained in the previous blog post, when an allocation is quarantined, its contents are overwritten with a special bit pattern. If the allocation is used later, the pattern will often be interpreted as an invalid memory address, causing a crash when the process attempts to access memory at that address. Since the dereferenced address remains within a small, predictable memory range, we can distinguish MiraclePtr crashes from other crashes.
Although this approach has its limitations — such as not being able to obtain stack traces from allocation and deallocation times like AddressSanitizer does — it has enabled us to detect and fix vulnerabilities. Last year, six critical severity vulnerabilities were identified in the default setup of Chrome Stable, the version most people use. Impressively, five of the six were discovered while investigating MiraclePtr crash reports! One particularly interesting example is CVE-2022-3038. The issue was discovered through MiraclePtr crash reports and fixed in Chrome 105. Several months later, Google's Threat Analysis Group discovered an exploit for that vulnerability used in the wild against clients of a different Chromium-based browser that hadn’t shipped the fix yet.
To further enhance our crash analysis capabilities, we've recently launched an experimental feature that allows us to collect additional information for MiraclePtr crashes, including stack traces. This effectively shortens the average crash report investigation time.
MiraclePtr enables us to have robust protection against use-after-free bug exploits, but there is a performance cost associated with it. Therefore, we have conducted experiments on each platform where we have shipped MiraclePtr, which we used in our decision-making process.
The main cost of MiraclePtr is memory. Specifically, the memory usage of the browser process increased by 5.5-8% on desktop platforms and approximately 2% on Android. Yet, when examining the holistic memory usage across all processes, the impact remains within a moderate 1-3% range to lower percentiles only.
The main cause of the additional memory usage is the extra size to allocate the reference count. One might think that adding 4 bytes to each allocation wouldn’t be a big deal. However, there are many small allocations in Chrome, so even the 4B overhead is not negligible. Moreover, PartitionAlloc also uses pre-defined allocation bucket sizes, so this extra 4B pushes certain allocations (particularly power-of-2 sized) into a larger bucket, e.g. 4096B → 5120B.
We also considered the performance cost. We verified that there were no regressions to the majority of our top-level performance metrics, including all of the page load metrics, like Largest Contentful Paint, First Contentful Paint and Cumulative Layout Shift. We did find a few regressions, such as a 10% increase in the 99th percentile of the browser process main thread contention metric, a 1.5% regression in First Input Delay on ChromeOS, and a 1.5% regression in tab startup time on Android. The main thread contention metric tries to estimate how often a user input can be delayed and so for example on Windows this was a change from 1.6% to 1.7% at the 99th percentile only. These are all minor regressions. There has been zero change in daily active usage, and we do not anticipate these regressions to have any noticeable impact on users.
In summary, MiraclePtr has proven to be effective in mitigating use-after-free vulnerabilities and enhancing the overall security of the Chrome browser. While there are performance costs associated with the implementation of MiraclePtr, our analysis suggests that the benefits in terms of security improvements far outweigh these. We are committed to continually refining and expanding the feature to cover more areas. For example we are working to add coverage to third-party libraries used by the GPU process, and we plan to enable BRP on the renderer process. By sharing our findings and experiences, we hope to contribute to the broader conversation surrounding browser security and inspire further innovation in this crucial area.