Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in V8
DescriptionUse after free in V8
ComponentV8
Bug ClassUAF
Tracker511270083
Fix commitbb96b8e67ac4 (v8/v8) +1/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-08

Files Changed

  • src/inspector/v8-deep-serializer.cc
From bb96b8e67ac4a4482ce812ff27d8ec3e4a36116c Mon Sep 17 00:00:00 2001
From: Philip Pfaffe <[email protected]>
Date: Wed, 13 May 2026 11:13:38 +0000
Subject: [PATCH] [inspector] Return error response in value serialization

Fixed: 511270083
Change-Id: I673fc070de370a4ca0ec4d7fc52dc9fa6dc0f156
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7843197
Commit-Queue: Benedikt Meurer <[email protected]>
Reviewed-by: Benedikt Meurer <[email protected]>
Auto-Submit: Philip Pfaffe <[email protected]>
Cr-Commit-Position: refs/heads/main@{#107299}
---

diff --git a/src/inspector/v8-deep-serializer.cc b/src/inspector/v8-deep-serializer.cc
index 2bb04a6..cf83fb9 100644
--- a/src/inspector/v8-deep-serializer.cc
+++ b/src/inspector/v8-deep-serializer.cc
@@ -205,6 +205,7 @@
                                             additionalParameters,
 
                                             duplicateTracker, &serializedValue);
+    if (!response.IsSuccess()) return response;
     result.setValue("value", std::move(serializedValue));
   }
   return Response::Success();
Loading diff…

Original Bug Report

reported by [email protected]

UAF write in V8 Inspector deep serialization via ignored SerializeSet error

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential Use-After-Free (UAF) exists in the V8 inspector’s deep serialization when V8DeepSerializer::SerializeSet ignores errors. This leaves raw, dangling pointers in the duplicate tracker, which can be exploited for arbitrary memory corruption and remote code execution if the freed memory is reclaimed.

Affected files:

  • v8/src/inspector/v8-deep-serializer.cc
  • v8/src/inspector/v8-serialization-duplicate-tracker.cc
  • v8/src/inspector/value-mirror.cc
  • third_party/blink/renderer/core/inspector/thread_debugger_common_impl.cc

Estimated timestamp from git blame: 2023-06-19

Potential Consequence: Exploitation yields a highly controllable Use-After-Free (UAF) write primitive, potentially leading to arbitrary memory corruption and Remote Code Execution (RCE) in the renderer process.

Technical Summary: Initial logic and parameters are validated: an attacker can trigger deep serialization via CDP (Runtime.evaluate) on a crafted structure containing a Set and a custom JS getter. The V8SerializationDuplicateTracker accurately registers object references using v8::External mappings (circumventing MiraclePtr protections).

Standard processing applies during serialization, where a deeply nested DOM tree legitimately exhausts maxDepth, forcing a Response::ServerError and the destruction of the local ListValue containing previously processed Set elements.

The vulnerability triggers when V8DeepSerializer::SerializeSet unconditionally ignores this error state and returns Response::Success(). This bypass allows the outer serialization routine to immediately invoke the attacker-controlled JS getter. The getter performs targeted heap reclamation over the freed DictionaryValue memory and returns the original Set object. The V8SerializationDuplicateTracker blindly fetches the now-dangling raw pointer, executing setInteger operations directly on attacker-controlled std::unordered_map structures, finalizing the UAF write.

Potential Steps to Reproduce: (Note: These are potential steps as our tooling agent cannot currently execute code).

  1. Construct an Array where index 0 is a Set containing a target object and a deeply nested DOM tree.
  2. Assign a custom JS getter to index 1 of the Array.
  3. Trigger deep serialization via CDP (Runtime.evaluate with serializationOptions: {serialization: "deep"}).
  4. The deeply nested DOM tree causes an intentional serialization failure, freeing the target object’s DictionaryValue.
  5. SerializeSet ignores the error, advancing to index 1 and invoking the JS getter.
  6. The JS getter reclaims the freed memory with payload data and returns the target object, forcing a UAF write via the duplicate tracker.

Suggested Fix: Update V8DeepSerializer::SerializeSet in v8/src/inspector/v8-deep-serializer.cc to explicitly check and return the Response from SerializeArrayValue:

Response response = SerializeArrayValue(value->AsArray(), context, maxDepth, additionalParameters, duplicateTracker, &serializedValue);
if (!response.IsSuccess()) return response;

Evaluated with Chrome root at commit: eca8648a4e1cdfdda68c495a6003059fed641955


Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker