Chrome 91でリリースされた Clipboard Read-only Filesの挙動とセキュリティを調べてみた。
結果、仕様上は安全なことが分かった。
Clipboard Read-only Files とは
クリップボード上のファイルをブラウザ側がread-onlyで読み取ることができる機能。
以下htmlにアクセスしてから貼り付け (MacならCmd + Vまたは編集>貼り付け) すると、
コンソールにファイルの内容を表示できる。
<html>
<script>
window.addEventListener('paste', onPaste);
async function onPaste(e) {
let file = e.clipboardData.files[0];
console.log(await file.text());
}
</script>
</html>
Chromeはdrag & dropによるDataTransferを既にサポートしているが、
それをクリップボードでもサポートしようとして実装したものとのこと。
用途として、ファイルをe-mailに添付するときにdrag & dropではなく単にCtrl+C, Ctrl+Vで添付する、などがある。
参考: Feature: Clipboard: read-only files support
セキュリティ
「ユーザー操作がなくても勝手にクリップボード上のファイルの中身を読み取れるかどうか」試してみた。
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "v",
ctrlKey: false,
bubbles: true,
metaKey: true
})
);
で貼り付けのKeyboardEventを発生させてもpaste
は呼び出されなかった(セキュリティ的に当然だが)。
理由
paste イベントは、 ユーザーがブラウザーのユーザーインターフェイスで「貼り付け」操作を行ったときに発生します。
に「ユーザーがブラウザーのユーザーインターフェイスで」と書いてあるとおり、ユーザーが明示的に操作したときでないと発生しない。clipboardDataを読み込めるかどうかも同様。
参考: Element: paste イベント
なお、無理やりcreateしても意味なし
function triggerEvent(event) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true );
return document.getElementById("body").dispatchEvent(evt);
}
triggerEvent("paste")
xxx.html:16 Uncaught (in promise) TypeError: Cannot read property 'files' of undefined
at onPaste (xxx.html:16)
at triggerEvent (xxx.html:10)
at xxx.html:51
注意
ブラウザ上でのcopy
イベントはキャンセル可能なので
window.addEventListener('copy', (e) => {
e.preventDefault();
});
で妨げられる。よって、例えば
- 何らかの理由でユーザーが事前にファイルをクリップボードにコピーした
- ユーザーがWebサイト上でテキストをコピーする
- しかし、コピー操作は妨げられている
- ユーザーがクリップボード上にテキストがあると信じる
- ユーザーがWebサイト上でテキストを貼り付けようとする
- ファイルの中身が読み取られてしまう
ということはあり得る。
また、1を期待して「このサイトを閉じるにはCmd + Vを押してください」などと表示して貼り付け操作を促すこともなくはなさそう。
結論
ユーザーの明示的な操作がないとクリップボードの中身は読み込めないので仕様上は安全だが、クリップボード上にファイルがある状態での貼り付け操作を誘導することは可能。