CVE-2026-8583
Overview
Background
- `FRONT_FACING`
- an experimental WebXR session feature (
mojom::XRSessionFeature::FRONT_FACING) that selects the device’s front-facing camera for an immersive AR session. - `kWebXRIncubations`
- the
base::Featureflag that gates experimental (“incubation”) WebXR capabilities. - `GetSupportedFeatures` / `SetSupportedFeatures`
- the ARCore device code that declares which session features this backend advertises as supported.
- `kSupportedFeatures`
- the static feature list
GetSupportedFeaturesreturns.
Root Cause Analysis
Pre-fix, the ARCore backend advertised FRONT_FACING unconditionally: it is a plain entry in the static kSupportedFeatures list in GetSupportedFeatures (device/vr/android/arcore/arcore_device.cc:47), copied into device_features in the ArCoreDevice constructor at line 81 and passed to SetSupportedFeatures at line 97. By contrast, other experimental features in the same constructor are each guarded by a flag check — plane detection behind kWebXRPlaneDetection (lines 87-89) and WebGPU behind kWebXRWebGPUBinding (lines 93-95) — so FRONT_FACING was the outlier advertised regardless of the incubations flag. The invariant is “an experimental feature should only be advertised as supported when its feature flag is enabled,” matching how the renderer gates it; the browser-side backend failed to re-enforce that, so a request reaching the browser directly would find FRONT_FACING supported.
The fix removes FRONT_FACING from the unconditional kSupportedFeatures list and instead appends it to device_features only inside if (base::FeatureList::IsEnabled(features::kWebXRIncubations)). This TIGHTENS the policy: the backend now claims front-facing support only when the incubations flag is on, moving the gate from the renderer into the browser process.
kWebXRIncubations, so a renderer that bypassed the renderer-side gate found it supported; the fix adds the missing browser-process feature-flag check.Attack Path
- Bypass the renderer gate
A compromised renderer requests an immersive AR session that includes
FRONT_FACINGwithout honoring the renderer-side incubations check. (inferred) - Reach the unconditional backend list
The browser’s ARCore backend pre-fix lists
FRONT_FACINGinkSupportedFeatures(arcore_device.cc:47), so it treats the feature as supported with the flag off. - Session proceeds with front camera Because the backend advertised support, the feature is accepted and the AR session is configured for the front-facing camera. (inferred)
Impact Assessment
xr_permission_results.cc is not addressed by this commit (that file is unchanged), so that aspect is (inferred).Files Changed
device/vr/android/arcore/arcore_device.cc
Audit Directions
- Experimental features past the renderer gateFor each renderer-gated experimental capability, confirm the browser process independently re-checks the governing
base::Featurebefore advertising or granting it. - Unconditional capability listsAudit static “supported features” tables for experimental entries that belong behind a flag check like the surrounding conditional features.
- Renderer-trust assumptionsFlag browser-side code that assumes the renderer already enforced a policy, especially for sensitive device access such as cameras.
Patch
From d9ccb8c1268ff5ff402688eff7c2514666d589e3 Mon Sep 17 00:00:00 2001 From: Brandon Jones <[email protected]> Date: Wed, 01 Apr 2026 17:12:01 -0700 Subject: [PATCH] Gate front-facing WebXR on WebXRIncubations in browser proc Updates the ARCore WebXR backend to only allow support for the FRONT_FACING WebXR experimental feature if the WebXRIncubations flag has been enabled. Previously the backend always indicated it was allowed and the flag was handled in the renderer process. Bug: 497975477 Change-Id: Ie4348988e330eb27c37bf8bb08c1756ea97c5a25 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7722806 Reviewed-by: Brian Sheedy <[email protected]> Commit-Queue: Brandon Jones <[email protected]> Cr-Commit-Position: refs/heads/main@{#1608879} --- diff --git a/device/vr/android/arcore/arcore_device.cc b/device/vr/android/arcore/arcore_device.cc index 7d34e7c..3281756 100644 --- a/device/vr/android/arcore/arcore_device.cc +++ b/device/vr/android/arcore/arcore_device.cc @@ -43,8 +43,7 @@ mojom::XRSessionFeature::ANCHORS, mojom::XRSessionFeature::DEPTH, mojom::XRSessionFeature::IMAGE_TRACKING, - mojom::XRSessionFeature::HIT_TEST, - mojom::XRSessionFeature::FRONT_FACING}}; + mojom::XRSessionFeature::HIT_TEST}}; return *kSupportedFeatures; } @@ -94,6 +93,11 @@ device_features.emplace_back(mojom::XRSessionFeature::WEBGPU); } + // Only support Front Facing mode if the WebXR incubations flag is enabled. + if (base::FeatureList::IsEnabled(features::kWebXRIncubations)) { + device_features.emplace_back(mojom::XRSessionFeature::FRONT_FACING); + } + SetSupportedFeatures(device_features); }
Original Bug Report
Potential unauthorized WebXR front-facing camera activation from compromised renderer
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: A compromised renderer can bypass Blink feature gates and request the experimental FRONT_FACING WebXR feature via a direct Mojo IPC call. The browser process fails to properly validate permissions or feature flags for this capability, treating it as automatically granted once the base AR permission is obtained. This allows an attacker to secretly activate the user’s selfie camera and extract derived sensor data without explicit consent.
Affected files:
content/browser/xr/service/xr_permission_results.cccontent/browser/xr/service/vr_service_impl.ccdevice/vr/android/arcore/arcore_impl.ccdevice/vr/android/arcore/arcore_device.cccontent/browser/xr/service/browser_xr_runtime_impl.cc
Estimated timestamp from git blame: 2026-01-13
Summary
A security vulnerability exists in the WebXR implementation where the experimental FRONT_FACING camera feature can be activated by a compromised renderer without proper permission checks or validation of experimental feature flags in the browser process. This allows a malicious site to activate the user’s front-facing (selfie) camera and obtain derived sensor data (such as light estimation and hit test results) without explicit consent for front-facing camera usage.
Technical Details
WebXR sessions can request various features, including FRONT_FACING (using the device’s front-facing camera). This feature is experimental and gated in the Blink renderer by RuntimeEnabledFeatures::WebXRFrontFacingEnabled (tied to the kWebXRIncubations flag in third_party/blink/renderer/modules/xr/xr_utils.cc:281).
However, if a compromised renderer bypasses the Blink-side checks and directly requests a session via the VRService::RequestSession Mojo interface, the browser process (content/browser/xr/service/vr_service_impl.cc) fails to re-validate whether this feature is enabled for the origin or require specific user consent.
The flaw occurs in two places in the browser process:
- Missing Feature Flag Validation: The browser process does not check the
kWebXRIncubationsbase::Feature flag before granting theFRONT_FACINGfeature. It relies solely on whether the underlying device (e.g., ARCore) supports it (device/vr/android/arcore/arcore_device.cc:47unconditionally lists it inkSupportedFeatures). - Permission Logic Flaw: In
content/browser/xr/service/vr_service_impl.cc,VRServiceImpl::OnPermissionResultsForFeaturesvalidates requested features usingXrPermissionResults::HasPermissionsFor. The implementation ofXrPermissionResults::GetPermissionFor(content/browser/xr/service/xr_permission_results.cc:98) fails to mapFRONT_FACINGto a specific permission (returningstd::nullopt).HasPermissionsForincorrectly interprets thisnulloptas ‘always granted’ (lines 57-60) once the base session permission (e.g., theARpermission) has been obtained.
The base AR permission prompt shown to users (“wants to create a 3D map of your surroundings and track camera position”) implies the use of the rear camera. It does not clearly communicate that the front-facing camera will be used, which has different privacy implications (tracking the user’s face).
When FRONT_FACING is granted through this bypass, the ARCore implementation (device/vr/android/arcore/arcore_impl.cc:846) configures the AR session to use AR_CAMERA_CONFIG_FACING_DIRECTION_FRONT via ArSession_setCameraConfig.
Potential Attack Steps
Note: These steps are suggested based on code analysis; a working proof of concept has not yet been executed.
- An attacker compromises a renderer process (e.g., via a V8 vulnerability).
- The compromised renderer ensures it has transient user activation (e.g., triggered concurrently with a user click).
- The renderer crafts a raw Mojo IPC message to
device::mojom::VRService::RequestSession, requesting an immersive AR session (kImmersiveAr) and includingFRONT_FACING(enum value 17) in therequired_featuresarray. - The browser process receives the request and, since
FRONT_FACINGis supported by the device (ARCore), it proceeds without checking thekWebXRIncubationsfeature flag. - The browser prompts the user for the base
ARpermission (or uses a previously granted permission). - Because
content::XrPermissionResults::GetPermissionForreturnsstd::nulloptforFRONT_FACING, the browser assumes no additional permissions are required and marks the feature as granted. - The session is dispatched to the ARCore runtime, which configures the device to activate the front-facing (selfie) camera.
- The attacker uses other WebXR features (like
HIT_TESTorLIGHT_ESTIMATION, which also returnstd::nulloptand are auto-granted) to extract derived environmental and facial tracking data from the user.
Impact
An attacker can activate the front-facing camera (visible to the user but not explicitly authorized for selfie use) and obtain derived sensor data (LIGHT_ESTIMATION spherical harmonics, HIT_TEST results against the environment/face) without the user’s explicit consent for front-facing camera usage. While raw camera pixels require the CAMERA_ACCESS feature (which correctly maps to VIDEO_CAPTURE), the unauthorized activation of the selfie camera and the collection of derived data violates user privacy boundaries.
Suggested Fix
- Map Permission: Update
content::XrPermissionResults::GetPermissionFor(content/browser/xr/service/xr_permission_results.cc) to explicitly mapFRONT_FACINGto a relevant permission (e.g.,blink::PermissionType::VIDEO_CAPTUREor a new specific permission) rather than returningstd::nullopt. - Validate Feature Flags: The browser process (e.g., in
VRServiceImpl::RequestSessionorXRRuntimeManagerImpl) should explicitly checkbase::Featureflags (likekWebXRIncubations) for experimental WebXR features before accepting them from a renderer, regardless of whether the underlying hardware runtime supports them.
Evaluated with Chrome root at commit: a9cbf6e8b275fe4147435aa905f3b7f5a656f5f0
Results from 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.