Bug 1483552 - Disable Clipboard.readText outside of system/extension code. r=baku a=RyanVM
authorNika Layzell <nika@thelayzells.com>
Fri, 26 Oct 2018 16:51:51 +0000
changeset 500878 e6e5c054a7f88fbd91e4158e0f07ba9233687399
parent 500877 bdb1dac7b88620374edaf14fefa8adf20d96bfe3
child 500879 14f0164bcbe3e8e9dac79dead5b1e74adfc637aa
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, RyanVM
bugs1483552
milestone64.0
Bug 1483552 - Disable Clipboard.readText outside of system/extension code. r=baku a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D9734
dom/events/Clipboard.cpp
dom/events/Clipboard.h
dom/webidl/Clipboard.webidl
--- a/dom/events/Clipboard.cpp
+++ b/dom/events/Clipboard.cpp
@@ -179,17 +179,26 @@ Clipboard::WrapObject(JSContext* aCx, JS
 }
 
 /* static */ LogModule*
 Clipboard::GetClipboardLog()
 {
   return gClipboardLog;
 }
 
-bool
+/* static */ bool
+Clipboard::ReadTextEnabled(JSContext* aCx, JSObject* aGlobal)
+{
+  nsIPrincipal* prin = nsContentUtils::SubjectPrincipal(aCx);
+  return IsTestingPrefEnabled() ||
+    prin->GetIsAddonOrExpandedAddonPrincipal() ||
+    prin->GetIsSystemPrincipal();
+}
+
+/* static */ bool
 Clipboard::IsTestingPrefEnabled()
 {
   static bool sPrefCached = false;
   static bool sPrefCacheValue = false;
 
   if (!sPrefCached) {
     sPrefCached = true;
     Preferences::AddBoolVarCache(&sPrefCacheValue, "dom.events.testing.asyncClipboard");
--- a/dom/events/Clipboard.h
+++ b/dom/events/Clipboard.h
@@ -40,25 +40,31 @@ public:
                                      ErrorResult& aRv);
   already_AddRefed<Promise> Write(JSContext* aCx, DataTransfer& aData,
                                   nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
   already_AddRefed<Promise> WriteText(JSContext* aCx, const nsAString& aData,
                                     nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
 
   static LogModule* GetClipboardLog();
 
+  // Check if the Clipboard.readText API should be enabled for this context.
+  // This API is only enabled for Extension and System contexts, as there is no
+  // way to request the required permission for web content. If the clipboard
+  // API testing pref is enabled, ReadText is enabled for web content for
+  // testing purposes.
+  static bool ReadTextEnabled(JSContext* aCx, JSObject* aGlobal);
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 private:
   // Checks if dom.events.testing.asyncClipboard pref is enabled.
   // The aforementioned pref allows automated tests to bypass the security checks when writing to
   //  or reading from the clipboard.
-  bool IsTestingPrefEnabled();
+  static bool IsTestingPrefEnabled();
 
   already_AddRefed<Promise> ReadHelper(JSContext* aCx, nsIPrincipal& aSubjectPrincipal,
                                        ClipboardReadType aClipboardReadType, ErrorResult& aRv);
 
   ~Clipboard();
 
 
 };
--- a/dom/webidl/Clipboard.webidl
+++ b/dom/webidl/Clipboard.webidl
@@ -1,24 +1,25 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
- * http://www.w3.org/TR/geolocation-API
+ * https://w3c.github.io/clipboard-apis/
  *
  * Copyright © 2018 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 
 [SecureContext, Exposed=Window, Pref="dom.events.asyncClipboard"]
 interface Clipboard : EventTarget {
   [Pref="dom.events.asyncClipboard.dataTransfer", Throws, NeedsSubjectPrincipal]
   Promise<DataTransfer> read();
-  [Throws, NeedsSubjectPrincipal]
+  [Func="Clipboard::ReadTextEnabled", Throws, NeedsSubjectPrincipal]
   Promise<DOMString> readText();
+
   [Pref="dom.events.asyncClipboard.dataTransfer", Throws, NeedsSubjectPrincipal]
   Promise<void> write(DataTransfer data);
   [Throws, NeedsSubjectPrincipal]
   Promise<void> writeText(DOMString data);
 };
\ No newline at end of file