diff --git a/devtools/client/responsive.html/test/browser/browser_viewport_resizing_scrollbar.js b/devtools/client/responsive.html/test/browser/browser_viewport_resizing_scrollbar.js
index bfcf31bc50eb..3ef99861da10 100644
--- a/devtools/client/responsive.html/test/browser/browser_viewport_resizing_scrollbar.js
+++ b/devtools/client/responsive.html/test/browser/browser_viewport_resizing_scrollbar.js
@@ -52,7 +52,7 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
   await SpecialPowers.pushPrefEnv({
     set: [["devtools.responsive.metaViewport.enabled", true],
           ["layout.testing.overlay-scrollbars.always-visible", true],
-    ],
+          ["security.data_uri.unique_opaque_origin", false]],
   });
 
   const store = ui.toolWindow.store;
diff --git a/devtools/shared/webconsole/test/test_commands_other.html b/devtools/shared/webconsole/test/test_commands_other.html
index 0a94e52c0d2f..768ad73f5a2a 100644
--- a/devtools/shared/webconsole/test/test_commands_other.html
+++ b/devtools/shared/webconsole/test/test_commands_other.html
@@ -75,8 +75,14 @@ function testEnd() {
 let load = async function () {
   removeEventListener("load", load);
 
+  await new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [
+      ["security.data_uri.unique_opaque_origin", false],
+    ]}, resolve);
+  });
+
   // Open a content window to test XRay functionality on built in functions.
-  gWin = window.open("javascript:1"); 
+  gWin = window.open("data:text/html,");
   info ("Waiting for content window to load");
   gWin.onload = startTest;
 };
@@ -85,4 +91,3 @@ addEventListener("load", load);
 </script>
 </body>
 </html>
- 
\ No newline at end of file
diff --git a/devtools/shared/webconsole/test/test_jsterm_queryselector.html b/devtools/shared/webconsole/test/test_jsterm_queryselector.html
index 9c93da37ebc0..3a41dc19e9d1 100644
--- a/devtools/shared/webconsole/test/test_jsterm_queryselector.html
+++ b/devtools/shared/webconsole/test/test_jsterm_queryselector.html
@@ -148,8 +148,14 @@ function testEnd() {
 let load = async function () {
   removeEventListener("load", load);
 
+  await new Promise(resolve => {
+    SpecialPowers.pushPrefEnv({"set": [
+      ["security.data_uri.unique_opaque_origin", false],
+    ]}, resolve);
+  });
+
   // Open a content window to test XRay functionality on built in functions.
-  gWin = window.open("javascript:1");
+  gWin = window.open("data:text/html,");
   info ("Waiting for content window to load");
   gWin.onload = startTest;
 };
@@ -158,4 +164,3 @@ addEventListener("load", load);
 </script>
 </body>
 </html>
-
diff --git a/docshell/base/crashtests/914521.html b/docshell/base/crashtests/914521.html
index a65e6819d97d..ca3e9b63fdf8 100644
--- a/docshell/base/crashtests/914521.html
+++ b/docshell/base/crashtests/914521.html
@@ -23,6 +23,7 @@ function f()
 function init()
 {
   SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false],
     ["security.data_uri.block_toplevel_data_uri_navigations", false],
   ]}, start);
 }
@@ -32,6 +33,7 @@ function start()
     var html = "<script>" + f + "<\/script><body onload=f()>";
     var win = window.open("data:text/html," + encodeURIComponent(html), null, "width=300,height=300");
     win.finish = function() {
+      SpecialPowers.clearUserPref("security.data_uri.unique_opaque_origin");
       document.documentElement.removeAttribute("class");
     };
 }
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index cb2f7b6fc55c..c60f048ad8b9 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9989,7 +9989,9 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
         true,  // aInheritForAboutBlank
         isSrcdoc);
 
-    inheritPrincipal = inheritAttrs && !SchemeIsData(aLoadState->URI());
+    bool isURIUniqueOrigin = nsIOService::IsDataURIUniqueOpaqueOrigin() &&
+                             SchemeIsData(aLoadState->URI());
+    inheritPrincipal = inheritAttrs && !isURIUniqueOrigin;
   }
 
   nsLoadFlags loadFlags = mDefaultLoadFlags;
diff --git a/docshell/test/browser/browser_dataURI_unique_opaque_origin.js b/docshell/test/browser/browser_dataURI_unique_opaque_origin.js
index e09afa4118f2..e4b10bbf6a8a 100644
--- a/docshell/test/browser/browser_dataURI_unique_opaque_origin.js
+++ b/docshell/test/browser/browser_dataURI_unique_opaque_origin.js
@@ -1,3 +1,11 @@
+add_task(async function setup() {
+  Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", true);
+
+  registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("security.data_uri.unique_opaque_origin");
+  });
+});
+
 add_task(async function test_dataURI_unique_opaque_origin() {
   let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com");
   let browser = tab.linkedBrowser;
diff --git a/docshell/test/browser/browser_loadDisallowInherit.js b/docshell/test/browser/browser_loadDisallowInherit.js
index 1479bd35e5fa..b5157d80bceb 100644
--- a/docshell/test/browser/browser_loadDisallowInherit.js
+++ b/docshell/test/browser/browser_loadDisallowInherit.js
@@ -4,10 +4,13 @@
 function test() {
   waitForExplicitFinish();
 
+  // data: URI will only inherit principal only when the pref is false.
+  Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", false);
   // data: URIs will only open at the top level when the pref is false
   //   or the use of system principal but we can't use that to test here.
   Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", false);
   registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("security.data_uri.unique_opaque_origin");
     Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
   });
 
@@ -37,7 +40,7 @@ function startTest() {
 
       // Now load the URL normally
       loadURL(url, 0, artificialPrincipal, function() {
-        ok(!browser.contentPrincipal.equals(pagePrincipal), url + " should not inherit principal");
+        ok(browser.contentPrincipal.equals(pagePrincipal), url + " should inherit principal");
 
         // Now load the URL and disallow inheriting the principal
         let webNav = Ci.nsIWebNavigation;
diff --git a/docshell/test/chrome/test_bug565388.xul b/docshell/test/chrome/test_bug565388.xul
index 3d4691dae0ba..76b3745ffa91 100644
--- a/docshell/test/chrome/test_bug565388.xul
+++ b/docshell/test/chrome/test_bug565388.xul
@@ -68,7 +68,10 @@ function test() {
   win.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
 }
 
-
+addLoadEvent(function onLoad() {
+  SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false]]}, test);
+});
 
   ]]>
   </script>
diff --git a/docshell/test/chrome/test_principalInherit.xul b/docshell/test/chrome/test_principalInherit.xul
index ffa82791782c..47957b76a3cc 100644
--- a/docshell/test/chrome/test_principalInherit.xul
+++ b/docshell/test/chrome/test_principalInherit.xul
@@ -37,11 +37,15 @@ var gFrame;
 // fail to load when there's no principal to load them against. This only
 // matters when these tests fail (produces better error messages).
 var tests = [
-  function testInitiation(cb) {
+  function testInheritFromParent(cb) {
     gFrame = document.createXULElement("iframe");
+    loadListener(gFrame, function () {
+      is(window.inheritedFromParent, true, "load in type=content iframe inherited principal of same type parent");
+      cb();
+    });
     gFrame.setAttribute("type", "content");
+    gFrame.setAttribute("src", "data:text/html,<script>parent.inheritedFromParent = true;</script>");
     document.documentElement.appendChild(gFrame);
-    cb();
   },
   function testInheritFromCurrent_system(cb) {
     loadListener(gFrame, function () {
@@ -49,12 +53,35 @@ var tests = [
       cb();
     }, true);
     gFrame.setAttribute("src", "data:text/html,<script>parent.inheritedSystem = true;</script>");
+  },
+  function testInheritFromCreated(cb) {
+    // Open a new chrome window with a type="content" iframe, so that it has no
+    // same-type parent.
+    // Load a javascript: URI in it to ensure that GetInheritedPrincipal will
+    // force creation of a content viewer.
+    let xulWinURL = 'data:application/vnd.mozilla.xul+xml,<?xml version="1.0"?>' +
+                    '<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>';
+    let newWin = window.openDialog(xulWinURL, "chrome_window", "chrome");
+    loadListener(newWin, function () {
+      let frame = newWin.document.createXULElement("iframe");
+      frame.setAttribute("type", "content");
+      frame.setAttribute("src", "javascript:'1';");
+      loadListener(frame, function () {
+        is(frame.contentWindow.document.body.textContent, "1", "content viewer was created");
+        SimpleTest.executeSoon(function () {
+          newWin.close();
+          cb();
+        })
+      });
+      newWin.document.documentElement.appendChild(frame);
+    });
   }
 ];
 
 addLoadEvent(function onLoad() {
   ok(Components.stack, "this test must be run with the system principal");
-  nextTest();
+  SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false]]}, nextTest);
 });
 
 function loadListener(target, func) {
diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
index d245d826e520..54cdf9a089fb 100644
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -2291,8 +2291,9 @@ nsresult nsObjectLoadingContent::OpenChannel() {
       nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
 
   bool isData;
-  bool isURIUniqueOrigin =
-      NS_SUCCEEDED(mURI->SchemeIs("data", &isData)) && isData;
+  bool isURIUniqueOrigin = nsIOService::IsDataURIUniqueOpaqueOrigin() &&
+                           NS_SUCCEEDED(mURI->SchemeIs("data", &isData)) &&
+                           isData;
 
   if (inherit && !isURIUniqueOrigin) {
     securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
diff --git a/dom/base/test/test_data_uri.html b/dom/base/test/test_data_uri.html
index aa1c0fdbda77..c42c9e70e094 100644
--- a/dom/base/test/test_data_uri.html
+++ b/dom/base/test/test_data_uri.html
@@ -14,8 +14,10 @@
 <script>
 SimpleTest.waitForExplicitFinish();
 
+SpecialPowers.setBoolPref("security.data_uri.unique_opaque_origin", true);
 SpecialPowers.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", false);
 SimpleTest.registerCleanupFunction(() => {
+  SpecialPowers.clearUserPref("security.data_uri.unique_opaque_origin");
   SpecialPowers.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations");
 });
 
diff --git a/dom/base/test/test_x-frame-options.html b/dom/base/test/test_x-frame-options.html
index 52d03470214c..000672292fcc 100644
--- a/dom/base/test/test_x-frame-options.html
+++ b/dom/base/test/test_x-frame-options.html
@@ -15,7 +15,7 @@
 <script class="testbody" type="text/javascript">
 
 var path = "/tests/dom/base/test/";
-var isUnique = true;
+var isUnique = SpecialPowers.getBoolPref("security.data_uri.unique_opaque_origin");
 
 var testFramesLoaded = function() {
   var harness = SpecialPowers.wrap(document).getElementById("harness");
diff --git a/dom/clients/manager/ClientManager.cpp b/dom/clients/manager/ClientManager.cpp
index 0a4ab24a1107..c62ca4f0474e 100644
--- a/dom/clients/manager/ClientManager.cpp
+++ b/dom/clients/manager/ClientManager.cpp
@@ -9,6 +9,7 @@
 #include "ClientHandle.h"
 #include "ClientManagerChild.h"
 #include "ClientManagerOpChild.h"
+#include "ClientPrefs.h"
 #include "ClientSource.h"
 #include "mozilla/dom/WorkerHolderToken.h"
 #include "mozilla/dom/WorkerPrivate.h"
@@ -240,6 +241,8 @@ void ClientManager::Startup() {
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   sClientManagerThreadLocalIndexDuplicate = sClientManagerThreadLocalIndex;
 #endif
+
+  ClientPrefsInit();
 }
 
 // static
diff --git a/dom/clients/manager/ClientPrefs.cpp b/dom/clients/manager/ClientPrefs.cpp
new file mode 100644
index 000000000000..576eb9c83b69
--- /dev/null
+++ b/dom/clients/manager/ClientPrefs.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "ClientPrefs.h"
+
+#include "mozilla/Preferences.h"
+
+namespace mozilla {
+namespace dom {
+
+namespace {
+
+bool gDataURLUniqueOpaqueOrigin = false;
+
+}  // anonymous namespace
+
+void ClientPrefsInit() {
+  Preferences::AddBoolVarCache(&gDataURLUniqueOpaqueOrigin,
+                               "security.data_uri.unique_opaque_origin", false);
+}
+
+bool ClientPrefsGetDataURLUniqueOpaqueOrigin() {
+  return gDataURLUniqueOpaqueOrigin;
+}
+
+}  // namespace dom
+}  // namespace mozilla
diff --git a/dom/clients/manager/ClientPrefs.h b/dom/clients/manager/ClientPrefs.h
new file mode 100644
index 000000000000..594eda9af61e
--- /dev/null
+++ b/dom/clients/manager/ClientPrefs.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+#ifndef _mozilla_dom_ClientPrefs_h
+#define _mozilla_dom_ClientPrefs_h
+
+namespace mozilla {
+namespace dom {
+
+void ClientPrefsInit();
+
+bool ClientPrefsGetAllowUniqueOpaqueOrigin();
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // _mozilla_dom_ClientPrefs_h
diff --git a/dom/clients/manager/ClientValidation.cpp b/dom/clients/manager/ClientValidation.cpp
index cc5d92685fc5..1dcea78f08f4 100644
--- a/dom/clients/manager/ClientValidation.cpp
+++ b/dom/clients/manager/ClientValidation.cpp
@@ -6,6 +6,7 @@
 
 #include "ClientValidation.h"
 
+#include "ClientPrefs.h"
 #include "mozilla/net/MozURL.h"
 
 namespace mozilla {
@@ -108,6 +109,13 @@ bool ClientIsValidCreationURL(const PrincipalInfo& aPrincipalInfo,
         return true;
       }
 
+      // We have some tests that use data: URL windows without an opaque
+      // origin.  This should only happen when a pref is set.
+      if (!ClientPrefsGetDataURLUniqueOpaqueOrigin() &&
+          scheme.LowerCaseEqualsLiteral("data")) {
+        return true;
+      }
+
       // Otherwise don't support this URL type in the clients sub-system for
       // now.  This will exclude a variety of internal browser clients, but
       // currently we don't need to support those.  This function can be
@@ -125,7 +133,10 @@ bool ClientIsValidCreationURL(const PrincipalInfo& aPrincipalInfo,
              scheme.LowerCaseEqualsLiteral("resource") ||
              scheme.LowerCaseEqualsLiteral("blob") ||
              scheme.LowerCaseEqualsLiteral("javascript") ||
-             scheme.LowerCaseEqualsLiteral("view-source");
+             scheme.LowerCaseEqualsLiteral("view-source") ||
+
+             (!ClientPrefsGetDataURLUniqueOpaqueOrigin() &&
+              scheme.LowerCaseEqualsLiteral("data"));
     }
     case PrincipalInfo::TNullPrincipalInfo: {
       // A wide variety of clients can have a null principal.  For example,
diff --git a/dom/clients/manager/moz.build b/dom/clients/manager/moz.build
index 04dca5001676..5005b3a91580 100644
--- a/dom/clients/manager/moz.build
+++ b/dom/clients/manager/moz.build
@@ -40,6 +40,7 @@ UNIFIED_SOURCES += [
   'ClientOpenWindowOpChild.cpp',
   'ClientOpenWindowOpParent.cpp',
   'ClientOpenWindowUtils.cpp',
+  'ClientPrefs.cpp',
   'ClientPrincipalUtils.cpp',
   'ClientSource.cpp',
   'ClientSourceChild.cpp',
diff --git a/dom/html/test/test_fullscreen-api-race.html b/dom/html/test/test_fullscreen-api-race.html
index 2b91dcd46503..cc393731bc28 100644
--- a/dom/html/test/test_fullscreen-api-race.html
+++ b/dom/html/test/test_fullscreen-api-race.html
@@ -37,6 +37,7 @@ addLoadEvent(function () {
       ["full-screen-api.unprefix.enabled", true],
       ["full-screen-api.allow-trusted-requests-only", false],
       // Use legacy data: URI behavior to run test.
+      ["security.data_uri.unique_opaque_origin", false],
       ["security.data_uri.block_toplevel_data_uri_navigations", false],
     ]
   }, next);
diff --git a/dom/plugins/test/mochitest/browser_data_url_plugin.js b/dom/plugins/test/mochitest/browser_data_url_plugin.js
index be46246a6a98..f81df7a768d2 100644
--- a/dom/plugins/test/mochitest/browser_data_url_plugin.js
+++ b/dom/plugins/test/mochitest/browser_data_url_plugin.js
@@ -2,6 +2,9 @@ var rootDir = getRootDirectory(gTestPath);
 const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
 
 add_task(async function() {
+  await SpecialPowers.pushPrefEnv({
+    "set": [["security.data_uri.unique_opaque_origin", true]],
+  });
   is(navigator.plugins.length, 0,
      "plugins should not be available to chrome-privilege pages");
 
diff --git a/dom/security/test/csp/test_meta_csp_self.html b/dom/security/test/csp/test_meta_csp_self.html
index 3641060703de..43ef68c52972 100644
--- a/dom/security/test/csp/test_meta_csp_self.html
+++ b/dom/security/test/csp/test_meta_csp_self.html
@@ -46,7 +46,10 @@ function receiveMessage(event) {
   SimpleTest.finish();
 }
 
-  let DATA_URI = `data:text/html,
+SpecialPowers.pushPrefEnv(
+  {'set':[["security.data_uri.unique_opaque_origin", true]]},
+  function() {
+    let DATA_URI = `data:text/html,
       <html>
       <head>
         <meta http-equiv="Content-Security-Policy" content="img-src 'self'">
@@ -56,8 +59,8 @@ function receiveMessage(event) {
         <img id="testimg" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" />
       </body>
       </html>`;
-  document.getElementById("testframe").src = DATA_URI;
-
+    document.getElementById("testframe").src = DATA_URI;
+  });
 
 </script>
 </body>
diff --git a/dom/tests/mochitest/bugs/test_resize_move_windows.html b/dom/tests/mochitest/bugs/test_resize_move_windows.html
index 59352a08eac6..10f383e41f15 100644
--- a/dom/tests/mochitest/bugs/test_resize_move_windows.html
+++ b/dom/tests/mochitest/bugs/test_resize_move_windows.html
@@ -314,6 +314,7 @@ function checkChangeIsEnabled(aWindow, aNext)
 
 SpecialPowers.pushPrefEnv({
   "set": [["dom.disable_window_move_resize", false],
+          ["security.data_uri.unique_opaque_origin", false],
           ["security.data_uri.block_toplevel_data_uri_navigations", false],]},
                           function() {
 SimpleTest.waitForFocus(function() {
diff --git a/dom/tests/mochitest/chrome/test_resize_move_windows.xul b/dom/tests/mochitest/chrome/test_resize_move_windows.xul
index f2b7e5fcc4eb..099fb9cac29f 100644
--- a/dom/tests/mochitest/chrome/test_resize_move_windows.xul
+++ b/dom/tests/mochitest/chrome/test_resize_move_windows.xul
@@ -282,7 +282,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=565541
   }
 
   addLoadEvent(function onLoad() {
-    test();
+    SpecialPowers.pushPrefEnv({"set": [
+      ["security.data_uri.unique_opaque_origin", false]]}, test);
+  });
   ]]>
   </script>
 </window>
diff --git a/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
index af468085af60..b98133c8bef0 100644
--- a/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
+++ b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
@@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
 
 SimpleTest.waitForExplicitFinish();
 
-var isDataUnique = true;
+var isDataUnique = SpecialPowers.Services.prefs.getBoolPref("security.data_uri.unique_opaque_origin");
 var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 /**
diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
index 86927a10a0ff..4b1b2621dfb3 100644
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -161,7 +161,9 @@ nsresult ChannelFromScriptURL(
   rv = uri->SchemeIs("data", &isData);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (inheritAttrs && !isData) {
+  bool isURIUniqueOrigin =
+      net::nsIOService::IsDataURIUniqueOpaqueOrigin() && isData;
+  if (inheritAttrs && !isURIUniqueOrigin) {
     secFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 3d113afd8026..3b3c1a24b1b8 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5503,6 +5503,12 @@ pref("osfile.reset_worker_delay", 30000);
 
 pref("media.block-autoplay-until-in-foreground", true);
 
+// TODO: Bug 1324406: Treat 'data:' documents as unique, opaque origins
+// If true, data: URIs will be treated as unique opaque origins, hence will use
+// a NullPrincipal as the security context.
+// Otherwise it will inherit the origin from parent node, this is the legacy
+// behavior of Firefox.
+pref("security.data_uri.unique_opaque_origin", true);
 
 // If true, all toplevel data: URI navigations will be blocked.
 // Please note that manually entering a data: URI in the
diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp
index 43bf9223a521..e5e8719ae124 100644
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -183,6 +183,7 @@ static const char kProfileDoChange[] = "profile-do-change";
 uint32_t nsIOService::gDefaultSegmentSize = 4096;
 uint32_t nsIOService::gDefaultSegmentCount = 24;
 
+bool nsIOService::sIsDataURIUniqueOpaqueOrigin = false;
 bool nsIOService::sBlockToplevelDataUriNavigations = false;
 bool nsIOService::sBlockFTPSubresources = false;
 
@@ -259,6 +260,8 @@ nsresult nsIOService::Init() {
   } else
     NS_WARNING("failed to get observer service");
 
+  Preferences::AddBoolVarCache(&sIsDataURIUniqueOpaqueOrigin,
+                               "security.data_uri.unique_opaque_origin", false);
   Preferences::AddBoolVarCache(
       &sBlockToplevelDataUriNavigations,
       "security.data_uri.block_toplevel_data_uri_navigations", false);
@@ -1800,6 +1803,11 @@ nsIOService::SpeculativeAnonymousConnect(nsIURI* aURI, nsIPrincipal* aPrincipal,
   return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true);
 }
 
+/*static*/
+bool nsIOService::IsDataURIUniqueOpaqueOrigin() {
+  return sIsDataURIUniqueOpaqueOrigin;
+}
+
 /*static*/
 bool nsIOService::BlockToplevelDataUriNavigations() {
   return sBlockToplevelDataUriNavigations;
diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h
index 5aadfe7776f1..9f2d1a06db13 100644
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -99,6 +99,7 @@ class nsIOService final : public nsIIOService,
 
   bool IsLinkUp();
 
+  static bool IsDataURIUniqueOpaqueOrigin();
   static bool BlockToplevelDataUriNavigations();
 
   static bool BlockFTPSubresources();
@@ -219,6 +220,7 @@ class nsIOService final : public nsIIOService,
 
   bool mNetworkNotifyChanged;
 
+  static bool sIsDataURIUniqueOpaqueOrigin;
   static bool sBlockToplevelDataUriNavigations;
 
   static bool sBlockFTPSubresources;
diff --git a/netwerk/test/crashtests/675518.html b/netwerk/test/crashtests/675518.html
index 5a181f5c2795..191c0b618f8e 100644
--- a/netwerk/test/crashtests/675518.html
+++ b/netwerk/test/crashtests/675518.html
@@ -3,6 +3,7 @@
 function init()
 {
   SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false],
     ["security.data_uri.block_toplevel_data_uri_navigations", false],
   ]}, boom);
 }
@@ -22,6 +23,7 @@ function boom()
 
   frameWin.document.write("2...");
 
+  SpecialPowers.clearUserPref("security.data_uri.unique_opaque_origin");
 }
 
 </script>
diff --git a/testing/web-platform/meta/webmessaging/with-ports/016.html.ini b/testing/web-platform/meta/webmessaging/with-ports/016.html.ini
new file mode 100644
index 000000000000..5a178fac05f0
--- /dev/null
+++ b/testing/web-platform/meta/webmessaging/with-ports/016.html.ini
@@ -0,0 +1,2 @@
+[016.html]
+  prefs: [security.data_uri.unique_opaque_origin:true]
diff --git a/testing/web-platform/meta/webmessaging/without-ports/016.html.ini b/testing/web-platform/meta/webmessaging/without-ports/016.html.ini
new file mode 100644
index 000000000000..5a178fac05f0
--- /dev/null
+++ b/testing/web-platform/meta/webmessaging/without-ports/016.html.ini
@@ -0,0 +1,2 @@
+[016.html]
+  prefs: [security.data_uri.unique_opaque_origin:true]
diff --git a/toolkit/content/tests/widgets/test_menubar.xul b/toolkit/content/tests/widgets/test_menubar.xul
index aa0a3f1ffcd0..81353467f560 100644
--- a/toolkit/content/tests/widgets/test_menubar.xul
+++ b/toolkit/content/tests/widgets/test_menubar.xul
@@ -14,7 +14,8 @@
 SimpleTest.waitForExplicitFinish();
 function onLoad()
 {
-  runTest();
+  SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false]]}, runTest);
 }
 
 function runTest()
diff --git a/widget/tests/test_mouse_scroll.xul b/widget/tests/test_mouse_scroll.xul
index 56c1862b4509..427274dd91b2 100644
--- a/widget/tests/test_mouse_scroll.xul
+++ b/widget/tests/test_mouse_scroll.xul
@@ -22,7 +22,8 @@
 SimpleTest.waitForExplicitFinish();
 function onLoad()
 {
-  runTest();
+  SpecialPowers.pushPrefEnv({"set": [
+    ["security.data_uri.unique_opaque_origin", false]]}, runTest);
 }
 
 function runTest()