Chrome · FileSystemAccess API
CVE-2025-5065
Logic Error in FileSystemAccess API
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
content/browser/file_system_access/file_system_access_manager_impl.cc
Patch
From d5561f9e792bef4da69074b13cc04bbf38f95d69 Mon Sep 17 00:00:00 2001
From: Joey Arhar <jarhar@chromium.org>
Date: Fri, 18 Apr 2025 08:57:42 -0700
Subject: [PATCH] Make FileSystemAccess APIs consume user activation
User activation is consumed in the browser process instead of the
renderer process like input.showPicker() because consuming user
activation in the renderer would make the existing user activation check
in the browser process fail.
There is no browsertest because content::EvalJs() sets user activation
after running script, even with the flag to not run user activation, and
I don't know how to make it stop.
There is no web_test because consuming user activation in the browser
process does not notify the renderer process that it lost user
activation. It does not look like there is any existing interface to
make the browser tell the renderer that it lost user activation, only
the other way around.
I manually verified that the attached bug is fixed.
Spec issue: https://github.com/WICG/file-system-access/issues/458
Fixed: 40059071
Change-Id: Ia1f5ff63a8bdf6cdec70dea1406e9865123f96a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5735618
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Fergal Daly <fergal@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1448885}
---
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
index b5bd63d..9387190f 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -49,6 +49,7 @@
#include "content/browser/file_system_access/file_system_access_watcher_manager.h"
#include "content/browser/file_system_access/file_system_chooser.h"
#include "content/browser/file_system_access/fixed_file_system_access_permission_grant.h"
+#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
@@ -583,6 +584,18 @@
return;
}
+ // Consume user activation to address this issue: crbug.com/40059071
+ // TODO(crbug.com/411125804): Consider moving this user activation check to
+ // the renderer process or informing the renderer that it lost user
+ // activation.
+ if (content_browser_client
+ ->IsTransientActivationRequiredForShowFileOrDirectoryPicker(
+ web_contents)) {
+ FrameTreeNode::From(rfh)->UpdateUserActivationState(
+ blink::mojom::UserActivationUpdateType::kConsumeTransientActivation,
+ blink::mojom::UserActivationNotificationType::kNone);
+ }
+
// Don't show the file picker if there is an already active file picker for
// this render frame host.
GlobalRenderFrameHostId global_rfh_id = rfh->GetGlobalId();
Loading diff…
Original Bug Report
reported by nd...@protonmail.com
File picker UI spoof
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36
Steps to reproduce the problem: onmouseup = _ => { let fs = showOpenFilePicker(); open(‘https://www.google.com’); }
Click
What is the expected behavior? For open() to require its own user interaction. (it also allows for a window popunder) Stuff like window.close location.href should lose the FileSystemHandle anyway.
What went wrong? File picker shown on the wrong origin while keeping FileSystemHandle.
Did this work before? N/A
Chrome version: 99.0.4844.51 Channel: stable OS Version: 10.0
References
On This Page