|
@@ -0,0 +1,97 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Austin Sullivan <[email protected]>
|
|
|
+Date: Thu, 12 May 2022 04:52:20 +0000
|
|
|
+Subject: FSA: Sanitize .url files
|
|
|
+
|
|
|
+Bug: 1307930
|
|
|
+Change-Id: I7ed3cca5942a5334ba761d269bdd8961fa9d13fe
|
|
|
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3638698
|
|
|
+Reviewed-by: Marijn Kruisselbrink <[email protected]>
|
|
|
+Commit-Queue: Marijn Kruisselbrink <[email protected]>
|
|
|
+Auto-Submit: Austin Sullivan <[email protected]>
|
|
|
+Cr-Commit-Position: refs/heads/main@{#1002495}
|
|
|
+
|
|
|
+diff --git a/content/browser/file_system_access/file_system_chooser.cc b/content/browser/file_system_access/file_system_chooser.cc
|
|
|
+index 2f9d3b4dc999bbc7ddb16c05f2f1dd3ec12f6e15..5a16bd48c25a6768b35861a45d5eb726cbb52582 100644
|
|
|
+--- a/content/browser/file_system_access/file_system_chooser.cc
|
|
|
++++ b/content/browser/file_system_access/file_system_chooser.cc
|
|
|
+@@ -276,13 +276,15 @@ bool FileSystemChooser::IsShellIntegratedExtension(
|
|
|
+ base::FilePath::StringType extension_lower =
|
|
|
+ base::ToLowerASCII(GetLastExtension(extension));
|
|
|
+
|
|
|
+- // .lnk and .scf files may be used to execute arbitrary code (see
|
|
|
++ // '.lnk' and '.scf' files may be used to execute arbitrary code (see
|
|
|
+ // https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
|
|
|
+- // https://crbug.com/1227995, respectively). .local files are used by Windows
|
|
|
+- // to determine which DLLs to load for an application.
|
|
|
++ // https://crbug.com/1227995, respectively). '.local' files are used by
|
|
|
++ // Windows to determine which DLLs to load for an application. '.url' files
|
|
|
++ // can be used to read arbirtary files (see https://crbug.com/1307930).
|
|
|
+ if ((extension_lower == FILE_PATH_LITERAL("lnk")) ||
|
|
|
+ (extension_lower == FILE_PATH_LITERAL("local")) ||
|
|
|
+- (extension_lower == FILE_PATH_LITERAL("scf"))) {
|
|
|
++ (extension_lower == FILE_PATH_LITERAL("scf")) ||
|
|
|
++ (extension_lower == FILE_PATH_LITERAL("url"))) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+diff --git a/content/browser/file_system_access/file_system_chooser_browsertest.cc b/content/browser/file_system_access/file_system_chooser_browsertest.cc
|
|
|
+index 6033251755d68d83bc5c8300630eaebacbd2f3ce..7a2db77d2d1402e4aa22f154cee2c5b8df4a4359 100644
|
|
|
+--- a/content/browser/file_system_access/file_system_chooser_browsertest.cc
|
|
|
++++ b/content/browser/file_system_access/file_system_chooser_browsertest.cc
|
|
|
+@@ -1557,13 +1557,21 @@ IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, SuggestedName) {
|
|
|
+ "not_matching.jpg", false});
|
|
|
+
|
|
|
+ #if defined(OS_WIN)
|
|
|
+- // ".lnk", ".local", and ".scf" extensions should be sanitized.
|
|
|
+- name_infos.push_back({"dangerous_extension.local", ListValueOf(".local"),
|
|
|
+- true, "dangerous_extension.download", false});
|
|
|
++ // ".lnk", ".local", ".scf", and ".url" extensions should be sanitized.
|
|
|
+ name_infos.push_back({"dangerous_extension.lnk", ListValueOf(".lnk"), true,
|
|
|
+ "dangerous_extension.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.lnk", ListValueOf(".LNK"), true,
|
|
|
++ "dangerous_extension.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.LNK", ListValueOf(".lnk"), true,
|
|
|
++ "dangerous_extension.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.LNK", ListValueOf(".LNK"), true,
|
|
|
++ "dangerous_extension.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.local", ListValueOf(".local"),
|
|
|
++ true, "dangerous_extension.download", false});
|
|
|
+ name_infos.push_back({"dangerous_extension.scf", ListValueOf(".scf"), true,
|
|
|
+ "dangerous_extension.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.url", ListValueOf(".url"), true,
|
|
|
++ "dangerous_extension.download", false});
|
|
|
+ // Compound extensions ending in a dangerous extension should be sanitized.
|
|
|
+ name_infos.push_back({"dangerous_extension.png.local", ListValueOf(".local"),
|
|
|
+ true, "dangerous_extension.png.download", false});
|
|
|
+@@ -1571,6 +1579,8 @@ IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, SuggestedName) {
|
|
|
+ true, "dangerous_extension.png.download", false});
|
|
|
+ name_infos.push_back({"dangerous_extension.png.scf", ListValueOf(".scf"),
|
|
|
+ true, "dangerous_extension.png.download", false});
|
|
|
++ name_infos.push_back({"dangerous_extension.png.url", ListValueOf(".url"),
|
|
|
++ true, "dangerous_extension.png.download", false});
|
|
|
+ // Compound extensions not ending in a dangerous extension should not be
|
|
|
+ // sanitized.
|
|
|
+ name_infos.push_back({"dangerous_extension.local.png", ListValueOf(".png"),
|
|
|
+@@ -1579,6 +1589,8 @@ IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, SuggestedName) {
|
|
|
+ true, "dangerous_extension.lnk.png", true});
|
|
|
+ name_infos.push_back({"dangerous_extension.scf.png", ListValueOf(".png"),
|
|
|
+ true, "dangerous_extension.scf.png", true});
|
|
|
++ name_infos.push_back({"dangerous_extension.url.png", ListValueOf(".png"),
|
|
|
++ true, "dangerous_extension.url.png", true});
|
|
|
+ // Invalid characters should be sanitized.
|
|
|
+ name_infos.push_back({R"(inv*l:d\\ch%rבאמת!a<ters🤓.txt)",
|
|
|
+ ListValueOf(".txt"), true,
|
|
|
+diff --git a/content/browser/file_system_access/file_system_chooser_unittest.cc b/content/browser/file_system_access/file_system_chooser_unittest.cc
|
|
|
+index 9b27d6305bd00a19d94b5ec49f21a7ecff7ddc48..3082c088f9733de9335437278c0d023954a953d9 100644
|
|
|
+--- a/content/browser/file_system_access/file_system_chooser_unittest.cc
|
|
|
++++ b/content/browser/file_system_access/file_system_chooser_unittest.cc
|
|
|
+@@ -189,7 +189,7 @@ TEST_F(FileSystemChooserTest, IgnoreShellIntegratedExtensions) {
|
|
|
+ accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
|
|
|
+ u"", std::vector<std::string>({}),
|
|
|
+ std::vector<std::string>(
|
|
|
+- {"lnk", "foo.lnk", "foo.bar.local", "text", "local", "scf"})));
|
|
|
++ {"lnk", "foo.lnk", "foo.bar.local", "text", "local", "scf", "url"})));
|
|
|
+ SyncShowDialog(std::move(accepts), /*include_accepts_all=*/false);
|
|
|
+
|
|
|
+ ASSERT_TRUE(dialog_params.file_types);
|