Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactSide-channel information leakage in WebXR
DescriptionSide-channel information leakage in WebXR
ComponentWebXR
Bug ClassLogic Error
Tracker514427844
Fix commit143d56818160 (chromium/src) +3/-5
CISA KEVNot listed
CreditedGoogle
Disclosed2026-07-29

Files Changed

  • third_party/blink/renderer/modules/xr/xr_frame_provider.cc
From 143d56818160e58631e033c9e1827ab739cc13bb Mon Sep 17 00:00:00 2001
From: Alexander Cooper <alcooper@chromium.org>
Date: Wed, 10 Jun 2026 15:31:12 -0700
Subject: [PATCH] Clamp WebXR immersive session timestamps.

Update XRFrameProvider::UpdateImmersiveFrameTime to use
DOMWindowPerformance to obtain the frame timestamp. This ensures
that the timestamps returned to WebXR requestAnimationFrame callbacks
and stored in XRMesh/XRPlane lastChangedTime are properly clamped
to the document's time resolution, matching standard performance
timestamps.

Note that while this rounds the timestamp (typically to 100 microseconds
or 5 microseconds if cross-origin isolated), this resolution is much
finer than the frame delivery interval of XR devices (typically ~8-11ms),
so there is no risk of consecutive frames reporting the same timestamp.

Fixed: 514427844
Change-Id: Id41f5e8c5124cecfbf86e8f0870d362742c9df2a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7920430
Reviewed-by: Brandon Jones <bajones@chromium.org>
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1644924}
---

diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
index c2f16ef..3bd12a26 100644
--- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
+++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/core/frame/navigator.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
 #include "third_party/blink/renderer/modules/xr/xr_gpu_binding.h"
@@ -663,11 +664,8 @@
       *first_immersive_frame_time_ + current_frame_time_from_first_frame;
 
   double high_res_now_ms =
-      window->document()
-          ->Loader()
-          ->GetTiming()
-          .MonotonicTimeToZeroBasedDocumentTime(current_frame_time)
-          .InMillisecondsF();
+      DOMWindowPerformance::performance(*window)
+          ->MonotonicTimeToDOMHighResTimeStamp(current_frame_time);
 
   return high_res_now_ms;
 }
Loading diff…

Original Bug Report

reported by rj...@google.com

WebXR immersive session time-coarsening mitigation bypass

Flapjack, 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 WebXR API exposes an unclamped, high-resolution timestamp to JavaScript during immersive sessions, potentially bypassing standard side-channel mitigations. By failing to invoke ClampTimeResolution, requestAnimationFrame and XR object attributes leak microsecond-precise timings. This can be exploited to calibrate high-frequency counters for microarchitectural timing attacks.

Affected files:

  • third_party/blink/renderer/modules/xr/xr_frame_provider.cc
  • third_party/blink/renderer/modules/xr/xr_mesh.cc
  • third_party/blink/renderer/modules/xr/xr_plane.cc

Estimated timestamp from git blame: 2018-07-19

The vulnerability allows an attacker to bypass time-coarsening mitigations, obtaining a microsecond-precision clock via XRSession.requestAnimationFrame and XRMesh/XRPlane.lastChangedTime, which facilitates microarchitectural side-channel attacks like Spectre.

Vulnerability Details

Initial logic and parameters for WebXR session initiation, IPC frame data processing, and internal monotonic time delta synchronization (device_t_0 to renderer_t_N) within XRFrameProvider::UpdateImmersiveFrameTime are validated.

The calculated current_frame_time entirely bypasses Performance::ClampTimeResolution(), directly executing window->document()->Loader()->GetTiming().MonotonicTimeToZeroBasedDocumentTime(current_frame_time).InMillisecondsF().

This mathematically precise, unclamped high_res_now_ms value is instantly surfaced to the attacker’s JavaScript via callback_collection_->ExecuteCallbacks() and the last_changed_time_ attributes on meshes and planes, providing the unmitigated high-resolution anchor necessary for a worker-based SharedArrayBuffer side-channel synchronization attack.

Potential Trigger Steps

Note: These are suggested/potential steps; our tooling agent doesn’t yet have the ability to run code.

  1. The attacker provisions a WebXR immersive session environment and registers a session.requestAnimationFrame callback.
  2. Standard processing applied to capture the incoming XRFrameData during the frame tick.
  3. The attacker runtime directly accesses the unclamped time argument from the callback (or the .lastChangedTime attribute on XRMesh/XRPlane objects) to anchor and synchronize an external high-frequency counter within a parallel worker, recovering a precise clock for timing probes.

Suggested Fix

Wrap the calculated monotonic time delta in Performance::ClampTimeResolution (or the equivalent TimeClamper::ClampTimeResolution) prior to converting it to InMillisecondsF() and exposing it to WebXR callbacks and object attributes.

Evaluated with Chrome root at commit: b7d0c4d810da1b31400f198c70d9720fc8f0e5a0


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.

View on issue tracker