CVE-2026-76025
Overview
Background
- File System Access API (FSA)
- Lets a web origin, after a user picker grant, read and write files/directories on the host. To prevent abuse, Chrome maintains a sensitive-path blocklist consulted by
ConfirmSensitiveEntryAccess. - `ChromeFileSystemAccessPermissionContext` blocklist
- A static table of
BlockPathentries inchrome/browser/file_system_access/chrome_file_system_access_permission_context.cc. Each entry blocks a path by absolute location, by a directory relative to aPathServicekey (e.g.base::DIR_HOME), or by a path suffix. - `BlockType`
kBlockAllChildrenblocks both read and write to a path and everything under it;kBlockWriteblocks only writes (reads stay allowed).CreateSuffixmatches any path ending in the given suffix (case-insensitively, per the test’s.GIT/CONFIGcase).- `AccessTrigger`
- Distinguishes
kOpen/kProgrammaticRead(reads) fromkSave/kProgrammaticWrite(writes), sokBlockWriteentries can gate writes while permitting reads.
Root Cause Analysis
This is a policy/blocklist gap (missing sensitive paths), not a use-after-free — the advisory’s “Use after free in FileSystem” is not substantiated by the diff, which only adds static BlockPath entries and a unit test. The root cause is that several security-sensitive locations were reachable via FSA because they were absent from the blocklist or only blocked on some platforms, so a granted origin could write to (or read) them and achieve persistence or code execution. The patch closes these holes:
*/.git/configand*/.git/modulesare nowCreateSuffix(..., kBlockWrite)on all platforms, alongside the pre-existing*/.git/hooks. Writing.git/config(e.g.core.fsmonitor/core.pager/core.sshCommand) or planting hooks/config inside submodule git dirs under.git/modulesyields command execution when the user next runs git. Reads stay allowed so web git clients keep working.~/.configis promoted from Linux/ChromeOS/Android-only to all platforms (kBlockAllChildren), since it holds config for many cross-platform tools.- Shell startup files in the home dir (
.bash_profile,.bash_login,.bashrc,.profile,.zshenv,.zprofile,.zshrc,.zlogin) are blocked on all platforms (including those Git Bash reads on Windows) — writing any of them gives shell code execution at next login/shell start. /devis now blocked on macOS (kBlockAllChildren), matching Linux.- On Linux/ChromeOS:
~/.local/share, legacy fontconfig~/.fonts.conf/~/.fonts.conf.d, and the NSS database dir~/.pkiare blocked (the old single~/.configLinux entry is removed since~/.configis now blocked globally above).
The companion unit test ConfirmSensitiveEntryAccess_GitConfigAndModulesWriteBlock pins the intended semantics: .git/config and everything under .git/modules abort for kSave/kProgrammaticWrite (including the case-variant .GIT/CONFIG) but are allowed for kOpen/kProgrammaticRead; sibling files like config.bak and a config outside .git remain allowed; and the .git directory itself is still savable. The _ExplicitPathBlock test is extended to assert /dev is blocked on macOS, and the path-enumeration test adds the new home-dir entries.
.git/config, .git/modules, shell rc/profile files, ~/.config, ~/.pki, /dev on macOS — so a granted web origin could write them and bypass the intended protection.Attack Path
- Obtain a grant Attacker site convinces the user to grant FSA access to a directory that contains (or is an ancestor of) a sensitive target — e.g. a checked-out git repository, or the home directory. (user-interaction gated; social-engineering step inferred)
- Locate the gap
Navigate to a path missing from the old blocklist:
<repo>/.git/config, a file under<repo>/.git/modules/<sub>, or a home-dir shell startup file /~/.configentry (platform-dependent pre-patch). - Write a payload
Write a malicious git config (
core.pager,core.sshCommand,core.fsmonitor, submodule hooks) or append to.bashrc/.zshrc/.bash_profile. - Trigger execution
The user later runs
gitin the repo, opens a shell, or logs in, executing the attacker’s content. - Primitive
Arbitrary command/code execution in the user’s context (or disclosure/tampering of NSS keys, fontconfig,
/dev), i.e. a sandbox/policy bypass escalating a file grant into host code execution.
Impact Assessment
~/.pki NSS DB) — a serious policy bypass, but not memory corruption and not a UAF despite the advisory label. Strength depends on the granted root and the victim later invoking git/a shell. Per the withhold guidance: the diff does substantiate a security root cause (a concrete blocklist bypass), so this is a solid write-up, with the class corrected from the advisory’s “UAF” to a policy bypass.Files Changed
chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.ccchrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
Audit Directions
- Cross-platform parity of the blocklistAudit every
BlockPathentry still guarded by a single-platform#iffor locations that are sensitive on other platforms too (the~/.configand/devgaps were exactly this). - Write-to-execute filesEnumerate files whose write yields execution/persistence (VCS configs/hooks, shell rc/profile, autostart, LD/DYLD config,
.gitconfig,.npmrc, CI configs) and confirm each is suffix/relative-blocked for write. - Suffix-match robustnessVerify
CreateSuffixmatching handles case, separators, and trailing components so.git/configvariants cannot evade (the test covers.GIT/CONFIG; check deeper nesting and symlinks). - Read-allowed sensitive dirsFor
kBlockWrite-only entries (reads allowed), confirm no read-only leak of secrets (e.g. ensure.git/configread exposure is acceptable vs~/.pkiwhich iskBlockAllChildren).
Patch
From d6f2c70dbb4cd97f6eaf62aed88c8f2e57ef3fce Mon Sep 17 00:00:00 2001
From: Mingyu Lei <leimy@chromium.org>
Date: Wed, 21 Oct 2026 23:00:11 -0700
Subject: [PATCH] FSA: Add missing sensitive paths to the blocklist
Several sensitive locations are still reachable through File System
Access because they are missing from the sensitive-path blocklist, or
are only blocked on some platforms. Add them:
- Block write access to */.git/config and */.git/modules on all
platforms, alongside */.git/hooks. Reads stay allowed, so web Git
clients can still read repository configuration.
- Block ~/.config on all platforms. It was only blocked on Linux,
ChromeOS and Android.
- Block shell startup files in the home directory on all platforms,
including the ones Git Bash reads on Windows.
- Block /dev on macOS, matching Linux.
- Block ~/.local/share, the legacy fontconfig files ~/.fonts.conf and
~/.fonts.conf.d, and the NSS database directory ~/.pki on Linux and
ChromeOS.
Bug: 572269631, 571913154, 569012015, 558362029
Bug: 569012543, 561996724, 559780982, 557367241
Test: unit_tests --gtest_filter=ChromeFileSystemAccessPermissionContextTest.*ConfirmSensitiveEntryAccess*
Change-Id: Ia6fe9e51807e8106fbc6ac69e28d550660e49b38
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8619619
Reviewed-by: Fergal Daly <fergal@chromium.org>
Commit-Queue: Mingyu Lei <leimy@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1724465}
---
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
index 112be22..be365904 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -441,10 +441,41 @@
// And limit access to ~/.gnupg as well.
BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"),
BlockType::kBlockAllChildren),
+ // ~/.config holds configuration for many cross-platform tools, so block
+ // it on all platforms, see crbug.com/569012015.
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".config"),
+ BlockType::kBlockAllChildren),
+ // Shell startup files in the home directory, including the ones read by
+ // Git Bash on Windows, see crbug.com/558362029.
+ BlockPath::CreateRelative(base::DIR_HOME,
+ FILE_PATH_LITERAL(".bash_profile"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME,
+ FILE_PATH_LITERAL(".bash_login"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".bashrc"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".profile"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".zshenv"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".zprofile"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".zshrc"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".zlogin"),
+ BlockType::kBlockAllChildren),
// Block write access to */.git/hooks, see crbug.com/465668234 and
// crbug.com/553115714.
BlockPath::CreateSuffix(FILE_PATH_LITERAL(".git/hooks"),
BlockType::kBlockWrite),
+ // Block write access to the repository config and to submodule git
+ // directories, which have their own hooks and config, see
+ // crbug.com/572269631 and crbug.com/571913154.
+ BlockPath::CreateSuffix(FILE_PATH_LITERAL(".git/config"),
+ BlockType::kBlockWrite),
+ BlockPath::CreateSuffix(FILE_PATH_LITERAL(".git/modules"),
+ BlockType::kBlockWrite),
#if BUILDFLAG(IS_WIN)
// Some Windows specific directories to block, basically all apps, the
// operating system itself, as well as configuration data for apps.
@@ -475,6 +506,10 @@
// volumes).
BlockPath::CreateAbsolute(FILE_PATH_LITERAL("/System/Volumes"),
BlockType::kBlockAllChildren),
+ // Block access to devices via /dev, matching Linux, see
+ // crbug.com/569012543.
+ BlockPath::CreateAbsolute(FILE_PATH_LITERAL("/dev"),
+ BlockType::kBlockAllChildren),
BlockPath::CreateRelative(base::DIR_APP_DATA,
BlockType::kBlockAllChildren),
// Block access to the current bundle directory.
@@ -525,14 +560,25 @@
BlockType::kBlockAllChildren),
BlockPath::CreateAbsolute(FILE_PATH_LITERAL("/etc"),
BlockType::kBlockAllChildren),
- // And block all of ~/.config, matching the similar restrictions on mac
- // and windows.
- BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".config"),
- BlockType::kBlockAllChildren),
// Block ~/.dbus as well, just in case, although there probably isn't much
// a website can do with access to that directory and its contents.
BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".dbus"),
BlockType::kBlockAllChildren),
+ // Block per-user application data, see crbug.com/561996724.
+ BlockPath::CreateRelative(base::DIR_HOME,
+ FILE_PATH_LITERAL(".local/share"),
+ BlockType::kBlockAllChildren),
+ // Block the legacy per-user fontconfig configuration, see
+ // crbug.com/559780982. The current location is under ~/.config.
+ BlockPath::CreateRelative(base::DIR_HOME,
+ FILE_PATH_LITERAL(".fonts.conf"),
+ BlockType::kBlockAllChildren),
+ BlockPath::CreateRelative(base::DIR_HOME,
+ FILE_PATH_LITERAL(".fonts.conf.d"),
+ BlockType::kBlockAllChildren),
+ // Block the per-user NSS database, see crbug.com/557367241.
+ BlockPath::CreateRelative(base::DIR_HOME, FILE_PATH_LITERAL(".pki"),
+ BlockType::kBlockAllChildren),
// And block all of ~/.cache, matching the similar restrictions on mac
// and windows.
BlockPath::CreateRelative(base::DIR_CACHE, BlockType::kBlockAllChildren),
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
index 1bd9323..d500135 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -862,9 +862,8 @@
TEST_F(ChromeFileSystemAccessPermissionContextTest,
ConfirmSensitiveEntryAccess_ExplicitPathBlock) {
-// Linux is the only OS where we have some blocked directories with explicit
-// paths (as opposed to PathService provided paths).
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
+ BUILDFLAG(IS_MAC)
// /dev should be blocked.
EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
permission_context(), PathInfo(FILE_PATH_LITERAL("/dev")),
@@ -1604,6 +1603,101 @@
SensitiveDirectoryResult::kAllowed);
}
+// Testing that writes to */.git/config and */.git/modules are blocked, while
+// reads stay allowed.
+TEST_F(ChromeFileSystemAccessPermissionContextTest,
+ ConfirmSensitiveEntryAccess_GitConfigAndModulesWriteBlock) {
+#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+ base::FilePath root(FILE_PATH_LITERAL("c:\\"));
+#else
+ base::FilePath root(FILE_PATH_LITERAL("/"));
+#endif
+ const base::FilePath git_dir =
+ root.Append(FILE_PATH_LITERAL("a")).Append(FILE_PATH_LITERAL(".git"));
+ const base::FilePath git_config = git_dir.Append(FILE_PATH_LITERAL("config"));
+ const base::FilePath git_modules =
+ git_dir.Append(FILE_PATH_LITERAL("modules"));
+ const base::FilePath submodule_dir =
+ git_modules.Append(FILE_PATH_LITERAL("sub"));
+
+ // .git/config is blocked for save and programmatic write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // .git/config is not blocked for read.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kOpen),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kProgrammaticRead),
+ SensitiveDirectoryResult::kAllowed);
+ // Case variations of .git/config are blocked for programmatic write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(root.Append(FILE_PATH_LITERAL("a"))
+ .Append(FILE_PATH_LITERAL(".GIT"))
+ .Append(FILE_PATH_LITERAL("CONFIG"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // Other files under .git, and files named config outside of .git, are
+ // allowed.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(git_dir.Append(FILE_PATH_LITERAL("config.bak"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(root.Append(FILE_PATH_LITERAL("a"))
+ .Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAllowed);
+
+ // .git/modules and everything inside it is blocked for save and programmatic
+ // write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("hooks"))
+ .Append(FILE_PATH_LITERAL("pre-commit"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // .git/modules is not blocked for read.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kOpen),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticRead),
+ SensitiveDirectoryResult::kAllowed);
+ // The .git directory itself is still allowed for save.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_dir), HandleType::kDirectory,
+ AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAllowed);
+}
+
#if BUILDFLAG(IS_ANDROID)
TEST_F(ChromeFileSystemAccessPermissionContextTest,
ConfirmSensitiveEntryAccess_ContentUri) {
@@ -1867,6 +1961,15 @@
{chrome::DIR_USER_DATA, nullptr, true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".ssh"), true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".config"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bash_profile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bash_login"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bashrc"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".profile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zshenv"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zprofile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zshrc"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zlogin"), true, false},
#if BUILDFLAG(IS_WIN)
{base::DIR_PROGRAM_FILES, nullptr, true, false},
@@ -1880,6 +1983,7 @@
#endif
#if BUILDFLAG(IS_MAC)
+ {kNoBasePathKey, FILE_PATH_LITERAL("/dev"), true, false},
{base::DIR_APP_DATA, nullptr, true, false},
{chrome::DIR_OUTER_BUNDLE, nullptr, true, false},
{base::DIR_HOME, FILE_PATH_LITERAL("Applications"), true, false},
@@ -1900,8 +2004,11 @@
{kNoBasePathKey, FILE_PATH_LITERAL("/sys"), true, false},
{kNoBasePathKey, FILE_PATH_LITERAL("/boot"), true, false},
{kNoBasePathKey, FILE_PATH_LITERAL("/etc"), true, false},
- {base::DIR_HOME, FILE_PATH_LITERAL(".config"), true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".dbus"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".local/share"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".fonts.conf"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".fonts.conf.d"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".pki"), true, false},
#endif
#if BUILDFLAG(IS_ANDROID)
Regression Test / PoC
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
index 1bd9323..d500135 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -862,9 +862,8 @@
TEST_F(ChromeFileSystemAccessPermissionContextTest,
ConfirmSensitiveEntryAccess_ExplicitPathBlock) {
-// Linux is the only OS where we have some blocked directories with explicit
-// paths (as opposed to PathService provided paths).
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
+ BUILDFLAG(IS_MAC)
// /dev should be blocked.
EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
permission_context(), PathInfo(FILE_PATH_LITERAL("/dev")),
@@ -1604,6 +1603,101 @@
SensitiveDirectoryResult::kAllowed);
}
+// Testing that writes to */.git/config and */.git/modules are blocked, while
+// reads stay allowed.
+TEST_F(ChromeFileSystemAccessPermissionContextTest,
+ ConfirmSensitiveEntryAccess_GitConfigAndModulesWriteBlock) {
+#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+ base::FilePath root(FILE_PATH_LITERAL("c:\\"));
+#else
+ base::FilePath root(FILE_PATH_LITERAL("/"));
+#endif
+ const base::FilePath git_dir =
+ root.Append(FILE_PATH_LITERAL("a")).Append(FILE_PATH_LITERAL(".git"));
+ const base::FilePath git_config = git_dir.Append(FILE_PATH_LITERAL("config"));
+ const base::FilePath git_modules =
+ git_dir.Append(FILE_PATH_LITERAL("modules"));
+ const base::FilePath submodule_dir =
+ git_modules.Append(FILE_PATH_LITERAL("sub"));
+
+ // .git/config is blocked for save and programmatic write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // .git/config is not blocked for read.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kOpen),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_config), HandleType::kFile,
+ AccessTrigger::kProgrammaticRead),
+ SensitiveDirectoryResult::kAllowed);
+ // Case variations of .git/config are blocked for programmatic write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(root.Append(FILE_PATH_LITERAL("a"))
+ .Append(FILE_PATH_LITERAL(".GIT"))
+ .Append(FILE_PATH_LITERAL("CONFIG"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // Other files under .git, and files named config outside of .git, are
+ // allowed.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(git_dir.Append(FILE_PATH_LITERAL("config.bak"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(root.Append(FILE_PATH_LITERAL("a"))
+ .Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAllowed);
+
+ // .git/modules and everything inside it is blocked for save and programmatic
+ // write.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("hooks"))
+ .Append(FILE_PATH_LITERAL("pre-commit"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticWrite),
+ SensitiveDirectoryResult::kAbort);
+ // .git/modules is not blocked for read.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_modules),
+ HandleType::kDirectory, AccessTrigger::kOpen),
+ SensitiveDirectoryResult::kAllowed);
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(),
+ PathInfo(submodule_dir.Append(FILE_PATH_LITERAL("config"))),
+ HandleType::kFile, AccessTrigger::kProgrammaticRead),
+ SensitiveDirectoryResult::kAllowed);
+ // The .git directory itself is still allowed for save.
+ EXPECT_EQ(ConfirmSensitiveEntryAccessSync(
+ permission_context(), PathInfo(git_dir), HandleType::kDirectory,
+ AccessTrigger::kSave),
+ SensitiveDirectoryResult::kAllowed);
+}
+
#if BUILDFLAG(IS_ANDROID)
TEST_F(ChromeFileSystemAccessPermissionContextTest,
ConfirmSensitiveEntryAccess_ContentUri) {
@@ -1867,6 +1961,15 @@
{chrome::DIR_USER_DATA, nullptr, true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".ssh"), true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".config"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bash_profile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bash_login"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".bashrc"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".profile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zshenv"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zprofile"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zshrc"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".zlogin"), true, false},
#if BUILDFLAG(IS_WIN)
{base::DIR_PROGRAM_FILES, nullptr, true, false},
@@ -1880,6 +1983,7 @@
#endif
#if BUILDFLAG(IS_MAC)
+ {kNoBasePathKey, FILE_PATH_LITERAL("/dev"), true, false},
{base::DIR_APP_DATA, nullptr, true, false},
{chrome::DIR_OUTER_BUNDLE, nullptr, true, false},
{base::DIR_HOME, FILE_PATH_LITERAL("Applications"), true, false},
@@ -1900,8 +2004,11 @@
{kNoBasePathKey, FILE_PATH_LITERAL("/sys"), true, false},
{kNoBasePathKey, FILE_PATH_LITERAL("/boot"), true, false},
{kNoBasePathKey, FILE_PATH_LITERAL("/etc"), true, false},
- {base::DIR_HOME, FILE_PATH_LITERAL(".config"), true, false},
{base::DIR_HOME, FILE_PATH_LITERAL(".dbus"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".local/share"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".fonts.conf"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".fonts.conf.d"), true, false},
+ {base::DIR_HOME, FILE_PATH_LITERAL(".pki"), true, false},
#endif
#if BUILDFLAG(IS_ANDROID)