0

When clipboard contains files, ignore other types such as text

Mac Finder, and some linux file managers write both a filenames item
(NSFilenamesPboardType on mac, text/uri-list on linux) to the clipboard,
and a text item (NSPasteboardTypeString on mac, text/plain on linux)
which contains a CR or newline separated list of full file paths.

Now that chrome has support for filenames on the clipboard, we will
ignore DataTransfer String types (item.kind == 'string') when we detect
that Files (item.kind == 'file') are available.

1/ Providing the full paths of files is a potential privacy risk.
Web pages will be able to use DataTransfer.files File.name to access
the name of a file, but not the full path.

2/ This matches the normal behavior for drag-and-drop file where we
provide the file objects, but do not also provide the text/plain file
paths.

This change will match Safari behavior on Mac, but will differ to
firefox on Mac and Linux which matches the old behavior of chrome prior
to chrome adding clipboard File support.

This is a non-issue on Windows since File Explorer does not place
additional text or image types on the clipboard for file copy.

This is a non-issue for the ChromeOS FilesApp which does not provide
text/plain paths, but will be a similar change to Linux for how we
interoperate with VM apps which may set full paths.

Bug: 1175483
Bug: 1214108
Change-Id: Ia4976558eab6edb71f5be196651b3f44af0fd1b0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927077
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: Darwin Huang <huangdarwin@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#889514}
This commit is contained in:
Joel Hockey
2021-06-04 23:48:55 +00:00
committed by Chromium LUCI CQ
parent b0dbacf9a3
commit b210d8ddf8
2 changed files with 14 additions and 0 deletions

@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
@ -156,6 +157,12 @@ void ClipboardHostImpl::ReadAvailableTypes(
std::vector<std::u16string> types;
clipboard_->ReadAvailableTypes(clipboard_buffer, CreateDataEndpoint().get(),
&types);
// If files are available, do not include other types such as text/plain
// which contain the full path on some platforms (http://crbug.com/1214108).
std::u16string filenames_type = base::UTF8ToUTF16(ui::kMimeTypeURIList);
if (base::Contains(types, filenames_type)) {
types = {filenames_type};
}
std::move(callback).Run(types);
}

@ -74,6 +74,7 @@ class ClipboardHostImplBrowserTest : public ContentBrowserTest {
ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
std::vector<std::string> expected;
std::vector<ui::FileInfo> file_infos;
std::vector<std::u16string> file_paths;
{
base::ScopedAllowBlockingForTesting allow_blocking;
for (const auto& f : files) {
@ -85,9 +86,15 @@ class ClipboardHostImplBrowserTest : public ContentBrowserTest {
auto b64 = base::Base64Encode(base::as_bytes(base::make_span(buf)));
expected.push_back(base::JoinString({f.name, f.type, b64}, ":"));
file_infos.push_back(ui::FileInfo(file, base::FilePath()));
file_paths.push_back(file.AsUTF16Unsafe());
}
ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
// Write both filenames (text/uri-list) and the full file paths
// (text/plain), and validate in the test that only the Files are exposed
// in the renderer (item.kind == 'file') and the String full paths are not
// included (http://crbug.com/1214108).
writer.WriteFilenames(ui::FileInfosToURIList(file_infos));
writer.WriteText(base::JoinString(file_paths, u"\n"));
}
// Send paste event and wait for JS promise to resolve with file data.