Wenxiang Qian, Zhixin Tu and Bin Li build browser-security infrastructure at the scale where Google ships 124 Chrome CVEs in a single quarter, and where public exploits for in-the-wild N-days can appear within hours of a patch landing. Waiting for your own build to rebase onto a fixed Chromium release is too slow. Their answer: an automated pipeline that reads a fresh CVE's patch, figures out which of Chromium's roughly 3,000 runtime feature switches can disable the vulnerable code path without a full rebuild, measures the performance cost of every viable option, and pushes the cheapest effective one to the affected client processes within hours, before turning to the real, permanent patch. This is defensive tooling for anyone shipping a Chromium-based product, and the team open-sourced the clustering tool behind it.
Post 34 of my Black Hat Asia 2026 series. Unlike most of the offensive research in this series, this talk is squarely about defence at scale, so I go into full detail rather than trimming it.
1. Why N-days, not zero-days, are the real day-to-day threat
A zero-day is dramatic but rare. An N-day, a vulnerability that's already been publicly patched upstream, but not yet in your shipped product, is the much more common and much cheaper attack an adversary can pull off: the patch itself often reveals exactly what was broken, and a working proof-of-concept frequently leaks or gets reconstructed within a day of disclosure. In 2026 Q1 alone, Chrome shipped fixes for 124 CVEs, a meaningful share High or Critical severity, several confirmed exploited in the wild before the patch. Google's own release cadence means a fix can take up to 14 weeks to reach a stable channel release, and of the vulnerabilities the team tracked in one window, roughly 87% had test cases (PoCs) fully restricted, but around 11% were openly public, more than enough to arm opportunistic attackers against anyone slow to update.
If you maintain a Chromium-based application (an embedded browser, a kiosk product, an enterprise client), you inherit this entire threat surface, and rebuilding your fork against every upstream security release is often too slow to matter.
2. A concrete morning: racing an in-the-wild CVE
The talk opens with a real incident timeline that motivates the whole system. At 5:06am local time, hours before a major nationwide red-team exercise where the team was defending, their monitoring flagged an in-the-wild exploited CVE. Over the next several hours: the patch and a developer-only PoC were obtained and tested against a range of precompiled Chromium versions; root-cause analysis was performed and the fix ported into their own codebase against unit tests, alongside setting up crash and social-media monitoring for early signs of exploitation; seven candidate defensive JS engine flags were proposed and the best one selected based on measured effectiveness; the chosen flag was tested against every shipped version of their app, with failures routed to a human specialist (one candidate flag turned out to add bytecode that caused a misalignment, quietly illustrating that not every flag that "should" work actually does cleanly); performance and stability testing completed and a specialist signed off, with a staged rollout beginning. By 11:45am, less than seven hours after the initial alert, their customers were protected by a temporary defensive flag. A public PoC leaked that same afternoon, and a fully working exploit was released publicly the next day. The team's mitigation shipped before either of those became widely available.
3. The five-stage system
Fig. 1 — Five stages, from a bug ID appearing to a defensive flag live in production.
3.1 Intelligence: tracking new bugs
New Chromium vulnerabilities are tracked through Google's own public release blog and bug tracker. Every disclosed vulnerability carries a Bug ID, which is the anchor the entire pipeline hangs off. Once a bug ID surfaces, an LLM parses the discussion thread between the reporter and Chromium developers to extract context automatically rather than requiring a human to read every thread.
3.2 What the patch actually says
With the bug ID in hand, git log --grep="Bug: BUGID" pulls every commit referencing it, giving the team the actual fix, and often a linked PoC or test case, plus the specific vulnerable code path. Critically, the commit and surrounding discussion usually explain why the vulnerability exists, not just what changed, which is what later steps need to identify a viable mitigation rather than just the eventual patch.
3.3 Exploit detection without a PoC
Not every CVE comes with a working reproduction case handed to defenders. The team's approach: combine what's known from the bug tracker and git history with an LLM to infer a behavioural signature for the vulnerability, then set up monitoring on the specific functions implicated in the root cause. The underlying observation is that attackers usually test their exploit against a target before using it for real, and a raw, unpolished PoC run against a hardened or differently-configured target often fails in a way that shows up as a measurable spike in crashes tied to the vulnerable function. Well-known, easy-to-trigger N-days produce the clearest, longest-lasting spikes, sometimes visible for days around a patch release, giving defenders an early warning signal even before a public PoC circulates.
4. Mitigation matching: connecting a CVE to a runtime switch
This is the technical core of the talk. Chromium ships with roughly 3,000 runtime-configurable switches across several categories (roughly 800 V8 JS engine flags, 1,100 Blink rendering-engine feature flags, 800 base-layer features, and 200 command-line switches). Many of these can disable or reroute a specific code path without recompiling the browser, which is exactly the lever needed for a same-day mitigation. The hard problem: given a fresh CVE and its patch, which of 3,000 switches, if any, actually covers the vulnerable code?
4.1 The naive approach doesn't scale
You could, in principle, compute how related every pair of source files in the codebase is to every other pair, but for a codebase the size of V8 alone (around 18,000 files), that's roughly 311 million ordered file pairs, computationally infeasible to reason about directly, and there's no labelled dataset saying "these files belong to the same subsystem" to train against.
4.2 Building relationships from commit history, unsupervised
The team's solution is a multi-stage, unsupervised pipeline that progressively narrows the problem:
- Files that change together are related. Iterating through the project's entire commit history, any two files that appear in the same commit become "friends," and the commit message itself often explains why they're related. This alone shrinks the relevant pair count from hundreds of millions to a few hundred thousand.
- TF-IDF over commit messages builds a shared vocabulary (the top ~3,000 terms across all commit messages) and represents each file as a weighted-term vector, letting the system distinguish "closely related" file pairs from merely "co-changed once" pairs, further shrinking the meaningfully-related set to tens of thousands.
- A Siamese neural network (two identical sub-networks sharing weights, trained on pairs of these TF-IDF vectors) learns to pull genuinely co-changed, semantically related files closer together in a compact learned representation space (a 64-dimensional embedding per file) while pushing unrelated files apart, reducing the relevant-pair count to roughly 18,000, one per file.
- Agglomerative clustering over that embedding space, using a distance threshold, then groups files into clusters that correspond, in practice, to Chromium's actual internal subsystems, each with its own cluster ID and a representative "most typical" file, ending with roughly 30 or so distinct subsystem clusters covering the whole codebase.
The result is effectively an unsupervised map of "which files belong to the same subsystem" across the entire project, trained purely from the project's own commit history and requiring no GPU, and the team has open-sourced this clustering tool.
4.3 Bridging a CVE to a JS flag through shared subsystem clusters
With that subsystem map in hand, the bridge is straightforward: a CVE's patch touches a specific set of source files, a JS engine flag's occurrences in the codebase (found by parsing the flag definitions and locating every place a flag is actually checked) also map to a specific set of source files. If a patch's files and a flag's occurrence files land in the same subsystem cluster, that flag is a strong candidate for mitigating that vulnerability, even with no prior knowledge linking the two directly. The team demonstrates this working, for instance, correctly linking a specific optimising-compiler-disabling flag to a type-confusion vulnerability whose patch touched files in that same compiler subsystem, purely through the cluster relationship, not a hand-maintained lookup table.
5. Deciding among many candidate flags: performance versus coverage
A single CVE often maps to several viable candidate flags, and picking blindly risks either degrading performance for every user constantly, or under-protecting against determined attackers. The team's approach: pre-test performance impact for all combinations of up to two flags against a standard JS benchmark suite, roughly 320,000 combinations in total (single flags plus all flag pairs), then rank candidates and select the option that touches the fewest code paths for the best measured performance, explicitly balancing "annoying your customers all the time with a performance hit" against "leaving them exposed to attackers some of the time."
6. Getting the mitigation live, correctly, per site
The final stage is genuinely tricky plumbing, not just picking a flag. A pre-warmed "spare" renderer process (used to reduce page-load latency) is started before the browser knows which site the user is about to visit, which conflicts directly with applying a per-site defensive flag, since the process is already running with generic settings by the time the destination site is known. The team's fix disables spare-process reuse specifically for navigations matching a site the mitigation strategy targets, trading a small amount of startup latency for correctness on protected sites. Separately, V8's flags can only be set once, at initialisation, so flags can't simply be toggled after a renderer process is already running; the team's approach keys custom per-process flag sets by child-process ID and merges them in at renderer startup, before V8 initialises, so each renderer process can launch with its own tailored flag set and the protection takes effect immediately for that process, without needing a full browser restart.
git log --grep="Bug: BUGID" against their own codebase, choosing the source patch from the closest available upstream version to minimise merge conflicts, and rolling that permanent fix out as soon as it's ready, at which point the temporary flag can be retired.7. Why this matters beyond Chromium specifically
The reusable idea here generalises well past browsers: any large codebase with (a) a public disclosure and patch process, (b) a rich set of already-shipped, runtime-toggleable feature flags, and (c) enough commit history to learn subsystem structure from, can in principle build the same kind of pipeline, patch lands → infer affected subsystem → match against existing runtime switches → rank by performance cost → deploy the cheapest effective one immediately, real patch continues in parallel. It's a genuinely different posture from "wait for the next full release," and it directly answers the observation, repeated across this whole series, that the gap between disclosure and real-world exploitation keeps shrinking.
Is a JS flag mitigation as good as the real patch?
No, and the team is explicit about this: it's a temporary measure to buy time while the permanent, upstream-validated patch is ported and rolled out through normal release channels. Flags are retired once the real fix ships.
Does disabling JIT/optimising-compiler flags break websites?
Some of the most powerful mitigation flags can, which is exactly why the performance/coverage decision stage exists, to avoid reaching for a maximally disruptive flag when a narrower one covers the same vulnerable code path with far less impact.
How does the system find candidate flags without a maintained mapping table?
By clustering the entire codebase into subsystems using commit co-change history and a Siamese network, then matching a CVE's patched files and a flag's occurrence files by shared cluster membership, an unsupervised approach that needs no hand-built lookup table and generalises to new CVEs automatically.
Can I use this tooling myself?
The subsystem-clustering component is open-sourced on GitHub (linked below) and runs on CPU alone, no GPU required, though building the full five-stage pipeline described in the talk (monitoring, matching, decision, enforcement) is a larger integration effort specific to your own Chromium-based product.
Takeaways
- N-days, not zero-days, are the practical day-to-day threat for anyone shipping Chromium: 124 CVEs in one recent quarter, with exploits sometimes appearing within a day of patch disclosure.
- A five-stage pipeline, intelligence, exploit detection, mitigation matching, decision, enforcement, turns a manual overnight scramble into a repeatable, largely automated response.
- The core technical trick: unsupervised subsystem clustering (commit co-change history, TF-IDF, a Siamese network, agglomerative clustering) links a fresh CVE's patched files to Chromium's ~3,000 existing runtime flags, with no hand-built mapping table.
- Candidate mitigations are ranked by measured performance cost versus code-path coverage, and deployed per-site via careful renderer-process and flag-initialisation plumbing.
- Flag-based mitigations are explicitly temporary; the real upstream patch is always applied in parallel and the flag retired once it ships.
References & further reading
- Black Hat Asia 2026 — this talk's official page — abstract, speaker bio, and slides/video when posted.
- Official talk recording on YouTube — Black Hat channel.
- Black Hat Asia 2026 — full Briefings schedule — every talk in the conference.
- project-cluster (GitHub) — the team's open-sourced unsupervised subsystem-clustering tool.
- Chrome Releases blog — the primary source the team monitors for new CVEs and bug IDs.
- Chromium bug tracker (crbug.com) — per-bug discussion, patches and linked test cases.