CVE-2026-113194
Overview
Fix not yet public
Original Bug Report
UI spoofing via unvalidated tooltip bounds in OOPIFs
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. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The browser-side implementation of keyboard-triggered tooltips for Out-of-Process IFrames (OOPIFs) fails to validate renderer-supplied bounds. A compromised renderer can exploit this to position a persistent native tooltip anywhere on the screen, potentially spoofing sensitive browser UI like the Omnibox.
Affected files:
content/browser/renderer_host/render_widget_host_view_child_frame.cccontent/browser/renderer_host/render_widget_host_view_aura.ccui/views/corewm/tooltip_controller.cc
Estimated timestamp from git blame: 2021-05-22
A potential vulnerability in how keyboard-triggered tooltips are handled for OOPIFs allows for UI spoofing on primary security surfaces. The root cause is a lack of bounds validation in RenderWidgetHostViewChildFrame::UpdateTooltipFromKeyboard.
Technical Details
When a renderer sends an UpdateTooltipFromKeyboard IPC (via blink.mojom.WidgetHost), the browser-side handler in RenderWidgetHostViewChildFrame transforms the origin of the provided bounds rect to root-view coordinates but forwards the renderer-supplied size unchanged to the root view:
// content/browser/renderer_host/render_widget_host_view_child_frame.cc
void RenderWidgetHostViewChildFrame::UpdateTooltipFromKeyboard(
const std::u16string& tooltip_text,
const gfx::Rect& bounds) {
// ...
gfx::Rect adjusted_bounds(TransformPointToRootCoordSpace(bounds.origin()),
bounds.size()); // size is not clamped
root_view->UpdateTooltipFromKeyboard(tooltip_text, adjusted_bounds);
}
The TransformPointToRootCoordSpace call does not clamp the point to the frame’s actual bounds. More importantly, the size is used to calculate the tooltip’s anchor point in ui/views/corewm/tooltip_controller.cc using bounds.bottom_center(). By providing an extremely large or manipulated size, a compromised renderer can place the anchor point at an arbitrary location on the display.
Furthermore, in RenderWidgetHostViewAura::UpdateTooltipFromKeyboard, the browser explicitly disables the tooltip’s hide timeout:
// content/browser/renderer_host/render_widget_host_view_aura.cc
tooltip_client->SetHideTooltipTimeout(window_, {});
This causes the spoofed tooltip to persist indefinitely until mouse or keyboard activity occurs. While the tooltip widget itself is click-through (accept_events=false), its high Z-order (ZOrderLevel::kFloatingUIElement) and native appearance allow it to effectively spoof security-sensitive UI components like the Omnibox or permission prompts.
Suggested steps to trigger (Potential)
- Compromise a renderer process hosting an OOPIF.
- From the compromised renderer, invoke the
UpdateTooltipFromKeyboardIPC with:tooltip_text: A string designed to spoof a security indicator (e.g., “https://google.com”).bounds: Agfx::Rectwith a large size calculated to place thebottom_center()over the browser’s Omnibox area.
- Observe that a native tooltip appears over the Omnibox and persists indefinitely while the user is inactive.
Fix Suggestion
In RenderWidgetHostViewChildFrame::UpdateTooltipFromKeyboard, the bounds should be intersected with or clamped to the frame’s visible intersection rect (available via the CrossProcessFrameConnector) before being forwarded to the root view. This ensures that tooltips can only be anchored within the space actually occupied by the frame.
Evaluated with Chrome root at commit: 1a8d40fc44df2088d5945c0bf53584038aa1614a
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
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.