[tbb-commits] [tor-browser/tor-browser-60.4.0esr-8.5-1] Bug 1469916, r=ckerschb, jkt

gk at torproject.org gk at torproject.org
Wed Jan 23 08:04:19 UTC 2019


commit 23c6e68b1208d20ea342d3d4693f1ea7c1050661
Author: Gijs Kruitbosch <gijskruitbosch at gmail.com>
Date:   Fri Jun 22 15:41:39 2018 +0100

    Bug 1469916, r=ckerschb,jkt
    
    --HG--
    extra : rebase_source : 180442deeef92f0e9202d76c5e4e46b630072d99
    extra : source : be11a32900298eb6fd4d18ad21b9a699995254c3
---
 browser/base/content/nsContextMenu.js              | 22 +++--
 browser/base/content/pageinfo/pageInfo.js          |  3 +-
 browser/base/content/utilityOverlay.js             |  3 +-
 browser/components/shell/nsMacShellService.cpp     |  4 +-
 devtools/shared/gcli/commands/screenshot.js        |  3 +-
 devtools/shim/devtools-startup.js                  | 22 ++++-
 dom/base/nsContentAreaDragDrop.cpp                 |  8 +-
 dom/base/nsContentAreaDragDrop.h                   |  1 +
 dom/tests/browser/browser.ini                      |  4 +
 dom/tests/browser/browser_persist_cookies.js       | 94 ++++++++++++++++++++++
 dom/tests/browser/mimeme.sjs                       | 26 ++++++
 .../browser/set-samesite-cookies-and-redirect.sjs  | 33 ++++++++
 .../PWebBrowserPersistDocument.ipdl                |  2 +
 .../WebBrowserPersistDocumentChild.cpp             |  5 ++
 .../WebBrowserPersistLocalDocument.cpp             |  8 ++
 .../WebBrowserPersistRemoteDocument.cpp            | 13 +++
 .../WebBrowserPersistRemoteDocument.h              |  3 +
 dom/webbrowserpersist/nsIWebBrowserPersist.idl     | 15 ++--
 .../nsIWebBrowserPersistDocument.idl               |  2 +
 dom/webbrowserpersist/nsWebBrowserPersist.cpp      | 45 ++++++-----
 dom/webbrowserpersist/nsWebBrowserPersist.h        |  3 +-
 toolkit/components/browser/nsWebBrowser.cpp        | 12 ++-
 toolkit/components/downloads/test/unit/head.js     |  3 +-
 .../viewsource/content/viewSourceUtils.js          |  6 +-
 toolkit/content/contentAreaUtils.js                | 28 +++++--
 .../content/tests/browser/browser_saveImageURL.js  |  3 +-
 .../mozapps/extensions/LightweightThemeManager.jsm |  3 +-
 27 files changed, 314 insertions(+), 60 deletions(-)

diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js
index 368d0475ac34..5cebd9c38c56 100644
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -986,12 +986,22 @@ nsContextMenu.prototype = {
       target: this.target,
     });
 
+    // Cache this because we fetch the data async
+    let {documentURIObject} = gContextMenuContentData;
+
     let onMessage = (message) => {
       mm.removeMessageListener("ContextMenu:SaveVideoFrameAsImage:Result", onMessage);
+      // FIXME can we switch this to a blob URL?
       let dataURL = message.data.dataURL;
-      saveImageURL(dataURL, name, "SaveImageTitle", true, false,
-                   document.documentURIObject, null, null, null,
-                   isPrivate);
+      saveImageURL(dataURL, name, "SaveImageTitle",
+                   true, // bypass cache
+                   false, // don't skip prompt for where to save
+                   documentURIObject, // referrer
+                   null, // document
+                   null, // content type
+                   null, // content disposition
+                   isPrivate,
+                   this.principal);
     };
     mm.addMessageListener("ContextMenu:SaveVideoFrameAsImage:Result", onMessage);
   },
@@ -1228,13 +1238,15 @@ nsContextMenu.prototype = {
       this._canvasToBlobURL(this.target).then(function(blobURL) {
         saveImageURL(blobURL, "canvas.png", "SaveImageTitle",
                      true, false, referrerURI, null, null, null,
-                     isPrivate);
+                     isPrivate,
+                     document.nodePrincipal /* system, because blob: */);
       }, Cu.reportError);
     } else if (this.onImage) {
       urlSecurityCheck(this.mediaURL, this.principal);
       saveImageURL(this.mediaURL, null, "SaveImageTitle", false,
                    false, referrerURI, null, gContextMenuContentData.contentType,
-                   gContextMenuContentData.contentDisposition, isPrivate);
+                   gContextMenuContentData.contentDisposition, isPrivate,
+                   this.principal);
     } else if (this.onVideo || this.onAudio) {
       urlSecurityCheck(this.mediaURL, this.principal);
       var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle";
diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js
index 86f548c74494..405b9443342d 100644
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -704,7 +704,8 @@ function saveMedia() {
         var saveAnImage = function(aURIString, aChosenData, aBaseURI) {
           uniqueFile(aChosenData.file);
           internalSave(aURIString, null, null, null, null, false, "SaveImageTitle",
-                       aChosenData, aBaseURI, null, false, null, gDocInfo.isContentWindowPrivate);
+                       aChosenData, aBaseURI, null, false, null,
+                       gDocInfo.isContentWindowPrivate, gDocInfo.principal);
         };
 
         for (var i = 0; i < rowArray.length; i++) {
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
index b73a01a0b0f3..a1ab9ddd1c9b 100644
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -258,7 +258,8 @@ function openLinkIn(url, where, params) {
 
     // ContentClick.jsm passes isContentWindowPrivate for saveURL instead of passing a CPOW initiatingDoc
     if ("isContentWindowPrivate" in params) {
-      saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI, null, params.isContentWindowPrivate);
+      saveURL(url, null, null, true, true, aNoReferrer ? null : aReferrerURI,
+              null, params.isContentWindowPrivate, aPrincipal);
     } else {
       if (!aInitiatingDoc) {
         Cu.reportError("openUILink/openLinkIn was called with " +
diff --git a/browser/components/shell/nsMacShellService.cpp b/browser/components/shell/nsMacShellService.cpp
index 0a2672d8f84b..9b46fb8eca87 100644
--- a/browser/components/shell/nsMacShellService.cpp
+++ b/browser/components/shell/nsMacShellService.cpp
@@ -155,8 +155,8 @@ nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement,
     loadContext = do_QueryInterface(docShell);
   }
 
-  return wbp->SaveURI(imageURI, nullptr,
-                      docURI, content->OwnerDoc()->GetReferrerPolicy(),
+  return wbp->SaveURI(imageURI, aElement->NodePrincipal(), nullptr,
+                      docURI, aElement->OwnerDoc()->GetReferrerPolicy(),
                       nullptr, nullptr,
                       mBackgroundFile, loadContext);
 }
diff --git a/devtools/shared/gcli/commands/screenshot.js b/devtools/shared/gcli/commands/screenshot.js
index fc1383225aa1..a64f6527c4c0 100644
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -558,7 +558,6 @@ var saveToFile = Task.async(function* (context, reply) {
   // the downloads toolbar button when the save is done.
   const nsIWBP = Ci.nsIWebBrowserPersist;
   const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
-                nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES |
                 nsIWBP.PERSIST_FLAGS_BYPASS_CACHE |
                 nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
   let isPrivate =
@@ -577,7 +576,9 @@ var saveToFile = Task.async(function* (context, reply) {
           isPrivate);
   let listener = new DownloadListener(window, tr);
   persist.progressListener = listener;
+  const principal = Services.scriptSecurityManager.getSystemPrincipal();
   persist.savePrivacyAwareURI(sourceURI,
+                              principal,
                               null,
                               document.documentURIObject,
                               Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
diff --git a/devtools/shim/devtools-startup.js b/devtools/shim/devtools-startup.js
index 9089812048db..3a0211b547a6 100644
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -43,6 +43,8 @@ ChromeUtils.defineModuleGetter(this, "CustomizableUI",
                                "resource:///modules/CustomizableUI.jsm");
 ChromeUtils.defineModuleGetter(this, "CustomizableWidgets",
                                "resource:///modules/CustomizableWidgets.jsm");
+ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
+                               "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "StartupBundle", function () {
   const url = "chrome://devtools-shim/locale/startup.properties";
@@ -901,16 +903,32 @@ const JsonView = {
       // Save original contents
       chrome.saveBrowser(browser);
     } else {
+      if (!message.data.startsWith("blob:null") || !browser.contentPrincipal.isNullPrincipal) {
+        Cu.reportError("Got invalid request to save JSON data");
+        return;
+      }
       // The following code emulates saveBrowser, but:
       // - Uses the given blob URL containing the custom contents to save.
       // - Obtains the file name from the URL of the document, not the blob.
+      // - avoids passing the document and explicitly passes system principal.
+      //   We have a blob created by a null principal to save, and the null
+      //   principal is from the child. Null principals don't survive crossing
+      //   over IPC, so there's no other principal that'll work.
       let persistable = browser.frameLoader;
       persistable.startPersistence(0, {
         onDocumentReady(doc) {
           let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
           let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
-          chrome.internalSave(message.data, doc, filename, null, doc.contentType,
-            false, null, null, null, doc, false, null, undefined);
+          chrome.internalSave(message.data, null, filename, null, doc.contentType,
+            false /* bypass cache */,
+            null, /* filepicker title key */
+            null, /* file chosen */
+            null, /* referrer */
+            null, /* initiating document */
+            false, /* don't skip prompt for a location */
+            null, /* cache key */
+            PrivateBrowsingUtils.isBrowserPrivate(browser), /* private browsing ? */
+            Services.scriptSecurityManager.getSystemPrincipal());
         },
         onError(status) {
           throw new Error("JSON Viewer's onSave failed in startPersistence");
diff --git a/dom/base/nsContentAreaDragDrop.cpp b/dom/base/nsContentAreaDragDrop.cpp
index 2b315267464d..55ed2d5aa480 100644
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -146,6 +146,7 @@ NS_IMPL_ISUPPORTS(nsContentAreaDragDropDataProvider, nsIFlavorDataProvider)
 // into the file system
 nsresult
 nsContentAreaDragDropDataProvider::SaveURIToFile(nsIURI* inSourceURI,
+                                                 nsIPrincipal* inTriggeringPrincipal,
                                                  nsIFile* inDestFile,
                                                  bool isPrivate)
 {
@@ -167,7 +168,8 @@ nsContentAreaDragDropDataProvider::SaveURIToFile(nsIURI* inSourceURI,
   persist->SetPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION);
 
   // referrer policy can be anything since the referrer is nullptr
-  return persist->SavePrivacyAwareURI(inSourceURI, nullptr, nullptr,
+  return persist->SavePrivacyAwareURI(inSourceURI,
+                                      inTriggeringPrincipal, nullptr, nullptr,
                                       mozilla::net::RP_Unset,
                                       nullptr, nullptr,
                                       inDestFile, isPrivate);
@@ -347,7 +349,9 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable *aTransferable,
     bool isPrivate;
     aTransferable->GetIsPrivateData(&isPrivate);
 
-    rv = SaveURIToFile(sourceURI, file, isPrivate);
+    nsCOMPtr<nsIPrincipal> principal;
+    aTransferable->GetRequestingPrincipal(getter_AddRefs(principal));
+    rv = SaveURIToFile(sourceURI, principal, file, isPrivate);
     // send back an nsIFile
     if (NS_SUCCEEDED(rv)) {
       CallQueryInterface(file, aData);
diff --git a/dom/base/nsContentAreaDragDrop.h b/dom/base/nsContentAreaDragDrop.h
index 978e74905414..eb3416dbfbf7 100644
--- a/dom/base/nsContentAreaDragDrop.h
+++ b/dom/base/nsContentAreaDragDrop.h
@@ -77,6 +77,7 @@ public:
   NS_DECL_NSIFLAVORDATAPROVIDER
 
   nsresult SaveURIToFile(nsIURI* inSourceURI,
+                         nsIPrincipal* inTriggeringPrincipal,
                          nsIFile* inDestFile, bool isPrivate);
 };
 
diff --git a/dom/tests/browser/browser.ini b/dom/tests/browser/browser.ini
index e1d853f1af5b..11cf9ebf2346 100644
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -55,6 +55,10 @@ skip-if = !e10s || (os == "win" && processor == "x86") # Large-Allocation requir
 [browser_localStorage_e10s.js]
 skip-if = !e10s # This is a test of e10s functionality.
 [browser_localStorage_privatestorageevent.js]
+[browser_persist_cookies.js]
+support-files =
+  set-samesite-cookies-and-redirect.sjs
+  mimeme.sjs
 [browser_test_focus_after_modal_state.js]
 support-files =
   focus_after_prompt.html
diff --git a/dom/tests/browser/browser_persist_cookies.js b/dom/tests/browser/browser_persist_cookies.js
new file mode 100644
index 000000000000..78f3966f3bbc
--- /dev/null
+++ b/dom/tests/browser/browser_persist_cookies.js
@@ -0,0 +1,94 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.org");
+const TEST_PATH2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
+
+var MockFilePicker = SpecialPowers.MockFilePicker;
+MockFilePicker.init(window);
+
+registerCleanupFunction(async function() {
+  info("Running the cleanup code");
+  MockFilePicker.cleanup();
+  Services.obs.removeObserver(checkRequest, "http-on-modify-request");
+  if (gTestDir && gTestDir.exists()) {
+    // On Windows, sometimes nsIFile.remove() throws, probably because we're
+    // still writing to the directory we're trying to remove, despite
+    // waiting for the download to complete. Just retry a bit later...
+    let succeeded = false;
+    while (!succeeded) {
+      try {
+        gTestDir.remove(true);
+        succeeded = true;
+      } catch (ex) {
+        await new Promise(requestAnimationFrame);
+      }
+    }
+  }
+});
+
+let gTestDir = null;
+
+
+function checkRequest(subject) {
+  let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
+  let spec = httpChannel.URI.spec;
+  // Ignore initial requests for page that sets cookies and its favicon, which may not have
+  // cookies.
+  if (httpChannel.URI.host == "example.org" && !spec.endsWith("favicon.ico") && !spec.includes("redirect.sjs")) {
+    let cookie = httpChannel.getRequestHeader("cookie");
+    is(cookie.trim(), "normalCookie=true", "Should have correct cookie in request for " + spec);
+  }
+}
+
+function createTemporarySaveDirectory() {
+  var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+  saveDir.append("testsavedir");
+  if (!saveDir.exists()) {
+    info("create testsavedir!");
+    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+  }
+  info("return from createTempSaveDir: " + saveDir.path);
+  return saveDir;
+}
+
+add_task(async function() {
+  await BrowserTestUtils.withNewTab("about:blank", async function(browser) {
+    Services.obs.addObserver(checkRequest, "http-on-modify-request");
+    BrowserTestUtils.loadURI(browser, TEST_PATH + "set-samesite-cookies-and-redirect.sjs");
+    // Test that the original document load doesn't send same-site cookies.
+    await BrowserTestUtils.browserLoaded(browser, true, TEST_PATH2 + "set-samesite-cookies-and-redirect.sjs");
+    // Now check the saved page.
+    // Create the folder the link will be saved into.
+    gTestDir = createTemporarySaveDirectory();
+    let destFile = gTestDir.clone();
+
+    MockFilePicker.displayDirectory = gTestDir;
+    let fileName;
+    MockFilePicker.showCallback = function(fp) {
+      info("showCallback");
+      fileName = fp.defaultString;
+      info("fileName: " + fileName);
+      destFile.append(fileName);
+      info("path: " + destFile.path);
+      MockFilePicker.setFiles([destFile]);
+      MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
+      info("done showCallback");
+    };
+    saveBrowser(browser);
+    await new Promise(async (resolve) => {
+      let dls = await Downloads.getList(Downloads.PUBLIC);
+      dls.addView({
+        onDownloadChanged(download) {
+          if (download.succeeded) {
+            dls.removeView(this);
+            dls.removeFinished();
+            resolve();
+          }
+        }
+      });
+    });
+  });
+});
diff --git a/dom/tests/browser/mimeme.sjs b/dom/tests/browser/mimeme.sjs
new file mode 100644
index 000000000000..9b92548f041d
--- /dev/null
+++ b/dom/tests/browser/mimeme.sjs
@@ -0,0 +1,26 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function handleRequest(request, response) {
+  let mimeType = request.queryString.match(/type=([a-z]*)/)[1];
+  switch (mimeType) {
+    case "css":
+      response.setHeader("Content-Type", "text/css");
+      response.write("#hi {color: red}");
+      break;
+    case "js":
+      response.setHeader("Content-Type", "application/javascript");
+      response.write("var foo;");
+      break;
+    case "png":
+      response.setHeader("Content-Type", "image/png");
+      response.write("");
+      break;
+    case "html":
+      response.setHeader("Content-Type", "text/html");
+      response.write("<body>I am a subframe</body>");
+      break;
+  }
+}
diff --git a/dom/tests/browser/set-samesite-cookies-and-redirect.sjs b/dom/tests/browser/set-samesite-cookies-and-redirect.sjs
new file mode 100644
index 000000000000..74a494db9dbc
--- /dev/null
+++ b/dom/tests/browser/set-samesite-cookies-and-redirect.sjs
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function handleRequest(request, response) {
+  // Set cookies and redirect for .org:
+  if (request.host.endsWith(".org")) {
+    response.setHeader("Set-Cookie", "normalCookie=true; path=/;", true);
+    response.setHeader("Set-Cookie", "laxHeader=true; path=/; SameSite=Lax", true);
+    response.setHeader("Set-Cookie", "strictHeader=true; path=/; SameSite=Strict", true);
+    response.write(`
+      <head>
+        <meta http-equiv='set-cookie' content='laxMeta=true; path=/; SameSite=Lax'>
+        <meta http-equiv='set-cookie' content='strictMeta=true; path=/; SameSite=Strict'>
+      </head>
+      <body>
+        <script>
+        document.cookie = 'laxScript=true; path=/; SameSite=Lax';
+        document.cookie = 'strictScript=true; path=/; SameSite=Strict';
+        location.href = location.href.replace(/\.org/, ".com");
+        </script>
+      </body>`);
+  } else {
+    let baseURI = "https://example.org/" + request.path.replace(/[a-z-]*\.sjs/, "mimeme.sjs?type=");
+    response.write(`
+      <link rel="stylesheet" type="text/css" href="${baseURI}css">
+      <iframe src="${baseURI}html"></iframe>
+      <script src="${baseURI}js"></script>
+      <img src="${baseURI}png">
+    `);
+  }
+}
diff --git a/dom/webbrowserpersist/PWebBrowserPersistDocument.ipdl b/dom/webbrowserpersist/PWebBrowserPersistDocument.ipdl
index ad6332763e68..7c2fc64c53d2 100644
--- a/dom/webbrowserpersist/PWebBrowserPersistDocument.ipdl
+++ b/dom/webbrowserpersist/PWebBrowserPersistDocument.ipdl
@@ -10,6 +10,7 @@ include protocol PFileDescriptorSet;
 include protocol PChildToParentStream; //FIXME: bug #792908
 include protocol PParentToChildStream; //FIXME: bug #792908
 
+include PBackgroundSharedTypes;
 include IPCStream;
 
 namespace mozilla {
@@ -29,6 +30,7 @@ struct WebBrowserPersistDocumentAttrs {
   nsString contentDisposition;
   uint32_t cacheKey;
   uint32_t persistFlags;
+  PrincipalInfo principal;
 };
 
 // IPDL doesn't have tuples, so this gives the pair of strings from
diff --git a/dom/webbrowserpersist/WebBrowserPersistDocumentChild.cpp b/dom/webbrowserpersist/WebBrowserPersistDocumentChild.cpp
index 4a8e31b6f4eb..7b893d145f7a 100644
--- a/dom/webbrowserpersist/WebBrowserPersistDocumentChild.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistDocumentChild.cpp
@@ -41,6 +41,7 @@ WebBrowserPersistDocumentChild::Start(nsIWebBrowserPersistDocument* aDocument)
         return;
     }
 
+    nsCOMPtr<nsIPrincipal> principal;
     WebBrowserPersistDocumentAttrs attrs;
     nsCOMPtr<nsIInputStream> postDataStream;
 #define ENSURE(e) do {           \
@@ -60,6 +61,10 @@ WebBrowserPersistDocumentChild::Start(nsIWebBrowserPersistDocument* aDocument)
     ENSURE(aDocument->GetContentDisposition(attrs.contentDisposition()));
     ENSURE(aDocument->GetCacheKey(&(attrs.cacheKey())));
     ENSURE(aDocument->GetPersistFlags(&(attrs.persistFlags())));
+
+    ENSURE(aDocument->GetPrincipal(getter_AddRefs(principal)));
+    ENSURE(ipc::PrincipalToPrincipalInfo(principal, &(attrs.principal())));
+
     ENSURE(aDocument->GetPostData(getter_AddRefs(postDataStream)));
 #undef ENSURE
 
diff --git a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
index d6527e47d7ca..6d706c39f1c2 100644
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -199,6 +199,14 @@ WebBrowserPersistLocalDocument::GetPostData(nsIInputStream** aStream)
     return history->GetPostData(aStream);
 }
 
+NS_IMETHODIMP
+WebBrowserPersistLocalDocument::GetPrincipal(nsIPrincipal** aPrincipal)
+{
+  nsCOMPtr<nsIPrincipal> nodePrincipal = mDocument->NodePrincipal();
+  nodePrincipal.forget(aPrincipal);
+  return NS_OK;
+}
+
 already_AddRefed<nsISHEntry>
 WebBrowserPersistLocalDocument::GetHistory()
 {
diff --git a/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.cpp b/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.cpp
index c7dcca8619da..cfe831cfb57d 100644
--- a/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.cpp
@@ -9,6 +9,9 @@
 #include "WebBrowserPersistResourcesParent.h"
 #include "WebBrowserPersistSerializeParent.h"
 #include "mozilla/Unused.h"
+#include "mozilla/ipc/BackgroundUtils.h"
+
+#include "nsIPrincipal.h"
 
 namespace mozilla {
 
@@ -23,6 +26,8 @@ WebBrowserPersistRemoteDocument
 , mAttrs(aAttrs)
 , mPostData(aPostData)
 {
+  nsresult rv;
+  mPrincipal = ipc::PrincipalInfoToPrincipal(mAttrs.principal(), &rv);
 }
 
 WebBrowserPersistRemoteDocument::~WebBrowserPersistRemoteDocument()
@@ -133,6 +138,14 @@ WebBrowserPersistRemoteDocument::GetPostData(nsIInputStream** aStream)
 }
 
 NS_IMETHODIMP
+WebBrowserPersistRemoteDocument::GetPrincipal(nsIPrincipal** aPrincipal)
+{
+    nsCOMPtr<nsIPrincipal> nodePrincipal = mPrincipal;
+    nodePrincipal.forget(aPrincipal);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 WebBrowserPersistRemoteDocument::ReadResources(nsIWebBrowserPersistResourceVisitor* aVisitor)
 {
     if (!mActor) {
diff --git a/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.h b/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.h
index 08d435903843..2808ac4b53c0 100644
--- a/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.h
+++ b/dom/webbrowserpersist/WebBrowserPersistRemoteDocument.h
@@ -13,6 +13,8 @@
 #include "nsIWebBrowserPersistDocument.h"
 #include "nsIInputStream.h"
 
+class nsIPrincipal;
+
 // This class is the XPCOM half of the glue between the
 // nsIWebBrowserPersistDocument interface and a remote document; it is
 // created by WebBrowserPersistDocumentParent when (and if) it
@@ -40,6 +42,7 @@ private:
     WebBrowserPersistDocumentParent* mActor;
     Attrs mAttrs;
     nsCOMPtr<nsIInputStream> mPostData;
+    nsCOMPtr<nsIPrincipal> mPrincipal;
 
     friend class WebBrowserPersistDocumentParent;
     WebBrowserPersistRemoteDocument(WebBrowserPersistDocumentParent* aActor,
diff --git a/dom/webbrowserpersist/nsIWebBrowserPersist.idl b/dom/webbrowserpersist/nsIWebBrowserPersist.idl
index 8de84f5e2904..9573a024eebf 100644
--- a/dom/webbrowserpersist/nsIWebBrowserPersist.idl
+++ b/dom/webbrowserpersist/nsIWebBrowserPersist.idl
@@ -13,6 +13,7 @@ interface nsIWebProgressListener;
 interface nsIFile;
 interface nsIChannel;
 interface nsILoadContext;
+interface nsIPrincipal;
 
 /**
  * Interface for persisting DOM documents and URIs to local or remote storage.
@@ -67,12 +68,6 @@ interface nsIWebBrowserPersist : nsICancelable
   const unsigned long PERSIST_FLAGS_APPEND_TO_FILE = 32768;
 
   /**
-   * Force relevant cookies to be sent with this load even if normally they
-   * wouldn't be.
-   */
-  const unsigned long PERSIST_FLAGS_FORCE_ALLOW_COOKIES = 65536;
-
-  /**
    * Flags governing how data is fetched and saved from the network.
    * It is best to set this value explicitly unless you are prepared
    * to accept the default values.
@@ -117,6 +112,8 @@ interface nsIWebBrowserPersist : nsICancelable
    * @param aURI       URI to save to file. Some implementations of this interface
    *                   may also support <CODE>nullptr</CODE> to imply the currently
    *                   loaded URI.
+   * @param aTriggeringPrincipal
+   *                   The triggering principal for the URI we're saving.
    * @param aCacheKey  An object representing the URI in the cache or
    *                   <CODE>nullptr</CODE>.  This can be a necko cache key,
    *                   an nsIWebPageDescriptor, or the currentDescriptor of an
@@ -146,7 +143,8 @@ interface nsIWebBrowserPersist : nsICancelable
    *
    * @throws NS_ERROR_INVALID_ARG One or more arguments was invalid.
    */
-  void saveURI(in nsIURI aURI, in nsISupports aCacheKey,
+  void saveURI(in nsIURI aURI, in nsIPrincipal aTriggeringPrincipal,
+      in nsISupports aCacheKey,
       in nsIURI aReferrer, in unsigned long aReferrerPolicy,
       in nsIInputStream aPostData,
       in string aExtraHeaders, in nsISupports aFile,
@@ -158,7 +156,8 @@ interface nsIWebBrowserPersist : nsICancelable
    *                   of intermediate data, etc.)
    * @see saveURI for all other parameter descriptions
    */
-  void savePrivacyAwareURI(in nsIURI aURI, in nsISupports aCacheKey,
+  void savePrivacyAwareURI(in nsIURI aURI,
+      in nsIPrincipal aTriggeringPrincipal, in nsISupports aCacheKey,
       in nsIURI aReferrer, in unsigned long aReferrerPolicy,
       in nsIInputStream aPostData,
       in string aExtraHeaders, in nsISupports aFile,
diff --git a/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl b/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
index ba5bea8b2906..f7aa146766d0 100644
--- a/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
+++ b/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
@@ -9,6 +9,7 @@
 interface nsIDOMDocument;
 interface nsIInputStream;
 interface nsIOutputStream;
+interface nsIPrincipal;
 interface nsITabParent;
 interface nsIWebBrowserPersistResourceVisitor;
 interface nsIWebBrowserPersistWriteCompletion;
@@ -61,6 +62,7 @@ interface nsIWebBrowserPersistDocument : nsISupports
   readonly attribute AString referrer;
   readonly attribute AString contentDisposition;
   readonly attribute nsIInputStream postData;
+  readonly attribute nsIPrincipal principal;
 
   /**
    * The cache key.  Unlike in nsISHEntry, where it's wrapped in an
diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
index fd6d9d0d9315..12e6c41c37d8 100644
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -84,6 +84,7 @@ struct nsWebBrowserPersist::DocData
     nsCOMPtr<nsIURI> mBaseURI;
     nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
     nsCOMPtr<nsIURI> mFile;
+    nsCOMPtr<nsIPrincipal> mPrincipal;
     nsCString mCharset;
 };
 
@@ -414,18 +415,20 @@ NS_IMETHODIMP nsWebBrowserPersist::SetProgressListener(
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::SaveURI(
-    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aURI, nsIPrincipal *aPrincipal, nsISupports *aCacheKey,
     nsIURI *aReferrer, uint32_t aReferrerPolicy,
     nsIInputStream *aPostData, const char *aExtraHeaders,
     nsISupports *aFile, nsILoadContext* aPrivacyContext)
 {
-    return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy,
-                               aPostData, aExtraHeaders, aFile,
-                               aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
+    bool isPrivate =
+      aPrivacyContext && aPrivacyContext->UsePrivateBrowsing();
+    return SavePrivacyAwareURI(aURI, aPrincipal, aCacheKey,
+                               aReferrer, aReferrerPolicy,
+                               aPostData, aExtraHeaders, aFile, isPrivate);
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::SavePrivacyAwareURI(
-    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aURI, nsIPrincipal *aPrincipal, nsISupports *aCacheKey,
     nsIURI *aReferrer, uint32_t aReferrerPolicy,
     nsIInputStream *aPostData, const char *aExtraHeaders,
     nsISupports *aFile, bool aIsPrivate)
@@ -440,8 +443,10 @@ NS_IMETHODIMP nsWebBrowserPersist::SavePrivacyAwareURI(
 
     // SaveURI doesn't like broken uris.
     mPersistFlags |= PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS;
-    rv = SaveURIInternal(aURI, aCacheKey, aReferrer, aReferrerPolicy,
-                         aPostData, aExtraHeaders, fileAsURI, false, aIsPrivate);
+    rv = SaveURIInternal(aURI, aPrincipal, aCacheKey,
+                         aReferrer, aReferrerPolicy,
+                         aPostData, aExtraHeaders, fileAsURI,
+                         false, aIsPrivate);
     return NS_FAILED(rv) ? rv : NS_OK;
 }
 
@@ -600,6 +605,13 @@ nsWebBrowserPersist::SerializeNextFile()
     }
 
     if (urisToPersist > 0) {
+        nsCOMPtr<nsIPrincipal> docPrincipal;
+        //XXXgijs I *think* this is already always true, but let's be sure.
+        MOZ_ASSERT(mDocList.Length() > 0,
+            "Should have the document for any walked URIs to persist!");
+        nsresult rv = mDocList.ElementAt(0)->mDocument->
+            GetPrincipal(getter_AddRefs(docPrincipal));
+        NS_ENSURE_SUCCESS_VOID(rv);
         // Persist each file in the uri map. The document(s)
         // will be saved after the last one of these is saved.
         for (auto iter = mURIMap.Iter(); !iter.Done(); iter.Next()) {
@@ -609,8 +621,6 @@ nsWebBrowserPersist::SerializeNextFile()
                 continue;
             }
 
-            nsresult rv;
-
             // Create a URI from the key.
             nsCOMPtr<nsIURI> uri;
             rv = NS_NewURI(getter_AddRefs(uri), iter.Key(),
@@ -632,7 +642,7 @@ nsWebBrowserPersist::SerializeNextFile()
 
             // The Referrer Policy doesn't matter here since the referrer is
             // nullptr.
-            rv = SaveURIInternal(uri, nullptr, nullptr,
+            rv = SaveURIInternal(uri, docPrincipal, nullptr, nullptr,
                                  mozilla::net::RP_Unset, nullptr, nullptr,
                                  fileAsURI, true, mIsPrivate);
             // If SaveURIInternal fails, then it will have called EndDownload,
@@ -1329,7 +1339,8 @@ nsWebBrowserPersist::AppendPathToURI(nsIURI *aURI, const nsAString & aPath, nsCO
 }
 
 nsresult nsWebBrowserPersist::SaveURIInternal(
-    nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
+    nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
+    nsISupports *aCacheKey, nsIURI *aReferrer,
     uint32_t aReferrerPolicy, nsIInputStream *aPostData,
     const char *aExtraHeaders, nsIURI *aFile,
     bool aCalcFileExt, bool aIsPrivate)
@@ -1385,7 +1396,7 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
     nsCOMPtr<nsIChannel> inputChannel;
     rv = NS_NewChannel(getter_AddRefs(inputChannel),
                        aURI,
-                       nsContentUtils::GetSystemPrincipal(),
+                       aTriggeringPrincipal,
                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                        nsIContentPolicy::TYPE_OTHER,
                        nullptr,  // aPerformanceStorage
@@ -1415,16 +1426,6 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
         }
     }
 
-    if (mPersistFlags & PERSIST_FLAGS_FORCE_ALLOW_COOKIES)
-    {
-        nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
-                do_QueryInterface(inputChannel);
-        if (httpChannelInternal) {
-            rv = httpChannelInternal->SetThirdPartyFlags(nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
-            MOZ_ASSERT(NS_SUCCEEDED(rv));
-        }
-    }
-
     // Set the referrer, post data and headers if any
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
     if (httpChannel)
diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.h b/dom/webbrowserpersist/nsWebBrowserPersist.h
index 17b570d783e7..b9a2e3da73b6 100644
--- a/dom/webbrowserpersist/nsWebBrowserPersist.h
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.h
@@ -57,7 +57,8 @@ public:
 private:
     virtual ~nsWebBrowserPersist();
     nsresult SaveURIInternal(
-        nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
+        nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
+        nsISupports *aCacheKey, nsIURI *aReferrer,
         uint32_t aReferrerPolicy, nsIInputStream *aPostData,
         const char *aExtraHeaders, nsIURI *aFile,
         bool aCalcFileExt, bool aIsPrivate);
diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp
index 40ac82210502..cdc3804fee73 100644
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -998,6 +998,7 @@ nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener)
 
 NS_IMETHODIMP
 nsWebBrowser::SaveURI(nsIURI* aURI,
+                      nsIPrincipal* aPrincipal,
                       nsISupports* aCacheKey,
                       nsIURI* aReferrer,
                       uint32_t aReferrerPolicy,
@@ -1007,12 +1008,14 @@ nsWebBrowser::SaveURI(nsIURI* aURI,
                       nsILoadContext* aPrivacyContext)
 {
   return SavePrivacyAwareURI(
-    aURI, aCacheKey, aReferrer, aReferrerPolicy, aPostData, aExtraHeaders,
-    aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
+    aURI, aPrincipal, aCacheKey, aReferrer, aReferrerPolicy, aPostData,
+    aExtraHeaders, aFile,
+    aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
 }
 
 NS_IMETHODIMP
 nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
+                                  nsIPrincipal* aPrincipal,
                                   nsISupports* aCacheKey,
                                   nsIURI* aReferrer,
                                   uint32_t aReferrerPolicy,
@@ -1050,8 +1053,9 @@ nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
   mPersist->SetPersistFlags(mPersistFlags);
   mPersist->GetCurrentState(&mPersistCurrentState);
 
-  rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy,
-                                     aPostData, aExtraHeaders, aFile, aIsPrivate);
+  rv = mPersist->SavePrivacyAwareURI(uri, aPrincipal, aCacheKey,
+                                     aReferrer, aReferrerPolicy, aPostData,
+                                     aExtraHeaders, aFile, aIsPrivate);
   if (NS_FAILED(rv)) {
     mPersist = nullptr;
   }
diff --git a/toolkit/components/downloads/test/unit/head.js b/toolkit/components/downloads/test/unit/head.js
index 63bf2ff884a7..6c5c1b095ada 100644
--- a/toolkit/components/downloads/test/unit/head.js
+++ b/toolkit/components/downloads/test/unit/head.js
@@ -299,7 +299,8 @@ function promiseStartLegacyDownload(aSourceUrl, aOptions) {
 
       // Start the actual download process.
       persist.savePrivacyAwareURI(
-        sourceURI, null, referrer, Ci.nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
+        sourceURI, Services.scriptSecurityManager.getSystemPrincipal(),
+        null, referrer, Ci.nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
         null, null, targetFile, isPrivate);
     }).catch(do_report_unexpected_exception);
 
diff --git a/toolkit/components/viewsource/content/viewSourceUtils.js b/toolkit/components/viewsource/content/viewSourceUtils.js
index 610667cde3cd..d91f3481f802 100644
--- a/toolkit/components/viewsource/content/viewSourceUtils.js
+++ b/toolkit/components/viewsource/content/viewSourceUtils.js
@@ -228,7 +228,11 @@ var gViewSourceUtils = {
           webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
           webBrowserPersist.progressListener = this.viewSourceProgressListener;
           let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_NO_REFERRER;
-          webBrowserPersist.savePrivacyAwareURI(uri, null, null, referrerPolicy, null, null, file, data.isPrivate);
+          let ssm = Services.scriptSecurityManager;
+          let principal = ssm.createCodebasePrincipal(data.uri,
+            browser.contentPrincipal.originAttributes);
+          webBrowserPersist.savePrivacyAwareURI(uri, principal, null, null,
+            referrerPolicy, null, null, file, data.isPrivate);
 
           let helperService = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
             .getService(Ci.nsPIExternalAppLauncher);
diff --git a/toolkit/content/contentAreaUtils.js b/toolkit/content/contentAreaUtils.js
index 48cf448798a5..fa5a7a56c935 100644
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -62,14 +62,15 @@ function forbidCPOW(arg, func, argname) {
 // - A linked document using Alt-click Save Link As...
 //
 function saveURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
-                 aSkipPrompt, aReferrer, aSourceDocument, aIsContentWindowPrivate) {
+                 aSkipPrompt, aReferrer, aSourceDocument,
+                 aIsContentWindowPrivate, aPrincipal) {
   forbidCPOW(aURL, "saveURL", "aURL");
   forbidCPOW(aReferrer, "saveURL", "aReferrer");
   // Allow aSourceDocument to be a CPOW.
 
   internalSave(aURL, null, aFileName, null, null, aShouldBypassCache,
                aFilePickerTitleKey, null, aReferrer, aSourceDocument,
-               aSkipPrompt, null, aIsContentWindowPrivate);
+               aSkipPrompt, null, aIsContentWindowPrivate, aPrincipal);
 }
 
 // Just like saveURL, but will get some info off the image before
@@ -112,7 +113,7 @@ const nsISupportsCString = Ci.nsISupportsCString;
  */
 function saveImageURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
                       aSkipPrompt, aReferrer, aDoc, aContentType, aContentDisp,
-                      aIsContentWindowPrivate) {
+                      aIsContentWindowPrivate, aPrincipal) {
   forbidCPOW(aURL, "saveImageURL", "aURL");
   forbidCPOW(aReferrer, "saveImageURL", "aReferrer");
 
@@ -156,7 +157,7 @@ function saveImageURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
 
   internalSave(aURL, null, aFileName, aContentDisp, aContentType,
                aShouldBypassCache, aFilePickerTitleKey, null, aReferrer,
-               null, aSkipPrompt, null, aIsContentWindowPrivate);
+               aDoc, aSkipPrompt, null, aIsContentWindowPrivate, aPrincipal);
 }
 
 // This is like saveDocument, but takes any browser/frame-like element
@@ -350,11 +351,15 @@ XPCOMUtils.defineConstant(this, "kSaveAsType_Text", kSaveAsType_Text);
  *        This parameter is provided when the aInitiatingDocument is not a
  *        real document object. Stores whether aInitiatingDocument.defaultView
  *        was private or not.
+ * @param aPrincipal [optional]
+ *        This parameter is provided when neither aDocument nor
+ *        aInitiatingDocument is provided. Used to determine what level of
+ *        privilege to load the URI with.
  */
 function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
                       aContentType, aShouldBypassCache, aFilePickerTitleKey,
                       aChosenData, aReferrer, aInitiatingDocument, aSkipPrompt,
-                      aCacheKey, aIsContentWindowPrivate) {
+                      aCacheKey, aIsContentWindowPrivate, aPrincipal) {
   forbidCPOW(aURL, "internalSave", "aURL");
   forbidCPOW(aReferrer, "internalSave", "aReferrer");
   forbidCPOW(aCacheKey, "internalSave", "aCacheKey");
@@ -430,8 +435,17 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
         : aInitiatingDocument.isPrivate;
     }
 
+    // We have to cover the cases here where we were either passed an explicit
+    // principal, or a 'real' document (with a nodePrincipal property), or an
+    // nsIWebBrowserPersistDocument which has a principal property.
+    let sourcePrincipal =
+      aPrincipal ||
+      (aDocument && (aDocument.nodePrincipal || aDocument.principal)) ||
+      (aInitiatingDocument && aInitiatingDocument.nodePrincipal);
+
     var persistArgs = {
       sourceURI,
+      sourcePrincipal,
       sourceReferrer: aReferrer,
       sourceDocument: useSaveDocument ? aDocument : null,
       targetContentType: (saveAsType == kSaveAsType_Text) ? "text/plain" : null,
@@ -482,8 +496,7 @@ function internalPersist(persistArgs) {
 
   // Calculate persist flags.
   const nsIWBP = Ci.nsIWebBrowserPersist;
-  const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
-                nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES;
+  const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
   if (persistArgs.bypassCache)
     persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
   else
@@ -530,6 +543,7 @@ function internalPersist(persistArgs) {
                          persistArgs.targetContentType, encodingFlags, kWrapColumn);
   } else {
     persist.savePrivacyAwareURI(persistArgs.sourceURI,
+                                persistArgs.sourcePrincipal,
                                 persistArgs.sourceCacheKey,
                                 persistArgs.sourceReferrer,
                                 Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
diff --git a/toolkit/content/tests/browser/browser_saveImageURL.js b/toolkit/content/tests/browser/browser_saveImageURL.js
index 970aaea43ca9..609db2cb2adc 100644
--- a/toolkit/content/tests/browser/browser_saveImageURL.js
+++ b/toolkit/content/tests/browser/browser_saveImageURL.js
@@ -36,7 +36,8 @@ add_task(async function preferred_API() {
       return image.href;
     });
 
-    saveImageURL(url, "image.jpg", null, true, false, null, null, null, null, false);
+    saveImageURL(url, "image.jpg", null, true, false, null, null, null, null,
+      false, gBrowser.contentPrincipal);
     // eslint-disable-next-line mozilla/no-cpows-in-tests
     let channel = gBrowser.contentDocumentAsCPOW.docShell.currentDocumentChannel;
     if (channel) {
diff --git a/toolkit/mozapps/extensions/LightweightThemeManager.jsm b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
index 720f27b48244..d5efecca0de7 100644
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -869,7 +869,8 @@ function _persistImage(sourceURL, localFileName, successCallback) {
 
   persist.progressListener = new _persistProgressListener(successCallback);
 
-  persist.saveURI(sourceURI, null,
+  let sourcePrincipal = Services.scriptSecurityManager.createCodebasePrincipal(sourceURI, {});
+  persist.saveURI(sourceURI, sourcePrincipal, null,
                   null, Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
                   null, null, targetURI, null);
 }





More information about the tbb-commits mailing list