Chrome · DevTools
CVE-2026-87617
UAF in DevTools
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
gettest/inspector/runtime/regress-523442920.js |
modified |
Files Changed
src/inspector/v8-console.cctest/inspector/runtime/regress-523442920-expected.txttest/inspector/runtime/regress-523442920.js
Patch
From 23294e43bec49915a9f3fb9f3b45acc559d1bd6e Mon Sep 17 00:00:00 2001 From: Yang Guo <[email protected]> Date: Mon, 10 Aug 2026 05:11:17 +0000 Subject: [PATCH] [inspector] Pin InspectedContext in ConsoleHelper to prevent UAF ConsoleHelper::injectedScript() previously dropped its local shared_ptr<InspectedContext> before returning the raw InjectedScript* pointer. If the CommandLineAPI inspect function was captured and invoked from a page script outside an active ContextScope, synchronous context destruction during object serialization caused a use-after-free in InjectedScript::wrapObjectMirror. Keep a std::shared_ptr<InspectedContext> in ConsoleHelper so the context remains pinned during inspectImpl execution. TAG=agy CONV=812b1007-2667-4bf3-8c0b-7669dff6da64 Fixed: 523442920 Change-Id: I96dcd0c3c04b02d3ab3a92a0a3dbb6a0876b25e8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8225404 Commit-Queue: Simon Zünd <[email protected]> Auto-Submit: Yang Guo <[email protected]> Reviewed-by: Simon Zünd <[email protected]> Cr-Commit-Position: refs/heads/main@{#109151} --- diff --git a/src/inspector/v8-console.cc b/src/inspector/v8-console.cc index 0fa7caf..0ad21a5 100644 --- a/src/inspector/v8-console.cc +++ b/src/inspector/v8-console.cc @@ -67,10 +67,9 @@ int groupId() const { return m_inspector->contextGroupId(contextId()); } InjectedScript* injectedScript(int sessionId) { - std::shared_ptr<InspectedContext> context = - m_inspector->getContext(groupId(), contextId()); - if (!context) return nullptr; - return context->getInjectedScript(sessionId); + m_inspectedContext = m_inspector->getContext(groupId(), contextId()); + if (!m_inspectedContext) return nullptr; + return m_inspectedContext->getInjectedScript(sessionId); } V8InspectorSessionImpl* session(int sessionId) { @@ -210,6 +209,7 @@ const v8::debug::ConsoleCallArguments& m_info; const v8::debug::ConsoleContext& m_consoleContext; V8InspectorImpl* m_inspector; + std::shared_ptr<InspectedContext> m_inspectedContext; }; void createBoundFunctionProperty( diff --git a/test/inspector/runtime/regress-523442920-expected.txt b/test/inspector/runtime/regress-523442920-expected.txt new file mode 100644 index 0000000..ac306d2 --- /dev/null +++ b/test/inspector/runtime/regress-523442920-expected.txt @@ -0,0 +1,2 @@ +Tests that destroying context during inspect does not cause UAF (regress-523442920). +Success (no crash). diff --git a/test/inspector/runtime/regress-523442920.js b/test/inspector/runtime/regress-523442920.js new file mode 100644 index 0000000..d3442cd --- /dev/null +++ b/test/inspector/runtime/regress-523442920.js @@ -0,0 +1,32 @@ +// Copyright 2026 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let {session, contextGroup, Protocol} = + InspectorTest.start('Tests that destroying context during inspect does not cause UAF (regress-523442920).'); + +(async function test() { + await Protocol.Runtime.enable(); + + // Capture CommandLineAPI inspect function. + await Protocol.Runtime.evaluate({ + expression: 'globalThis.savedInspect = inspect;', + includeCommandLineAPI: true, + }); + + // Call savedInspect from page-level execution where no ContextScope is active. + contextGroup.addScript(` + let e = new Error(); + delete e.name; + Object.defineProperty(Object.getPrototypeOf(e), 'name', { + get() { + inspector.fireContextDestroyed(); + return ''; + } + }); + savedInspect(e); + `); + + InspectorTest.log('Success (no crash).'); + InspectorTest.completeTest(); +})();
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/test/inspector/runtime/regress-523442920-expected.txt b/test/inspector/runtime/regress-523442920-expected.txt
new file mode 100644
index 0000000..ac306d2
--- /dev/null
+++ b/test/inspector/runtime/regress-523442920-expected.txt
@@ -0,0 +1,2 @@
+Tests that destroying context during inspect does not cause UAF (regress-523442920).
+Success (no crash).
diff --git a/test/inspector/runtime/regress-523442920.js b/test/inspector/runtime/regress-523442920.js
new file mode 100644
index 0000000..d3442cd
--- /dev/null
+++ b/test/inspector/runtime/regress-523442920.js
@@ -0,0 +1,32 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+let {session, contextGroup, Protocol} =
+ InspectorTest.start('Tests that destroying context during inspect does not cause UAF (regress-523442920).');
+
+(async function test() {
+ await Protocol.Runtime.enable();
+
+ // Capture CommandLineAPI inspect function.
+ await Protocol.Runtime.evaluate({
+ expression: 'globalThis.savedInspect = inspect;',
+ includeCommandLineAPI: true,
+ });
+
+ // Call savedInspect from page-level execution where no ContextScope is active.
+ contextGroup.addScript(`
+ let e = new Error();
+ delete e.name;
+ Object.defineProperty(Object.getPrototypeOf(e), 'name', {
+ get() {
+ inspector.fireContextDestroyed();
+ return '';
+ }
+ });
+ savedInspect(e);
+ `);
+
+ InspectorTest.log('Success (no crash).');
+ InspectorTest.completeTest();
+})();
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page