Bug 1881800 - chrome/system-privileged XHR should not use credentials, r=peterv,extension-reviewers,application-update-reviewers,decoder,mossop,robwu,releng-reviewers,bytesized,jcristau

Differential Revision: https://phabricator.services.mozilla.com/D203334
This commit is contained in:
Gijs Kruitbosch 2024-03-26 16:50:45 +00:00
parent 2bb8c173e0
commit 1e801cd396
11 changed files with 46 additions and 17 deletions

View file

@ -308,7 +308,7 @@ export var pktApi = (function () {
data.locale_lang = Services.locale.appLocaleAsBCP47; data.locale_lang = Services.locale.appLocaleAsBCP47;
data.consumer_key = oAuthConsumerKey; data.consumer_key = oAuthConsumerKey;
var request = new XMLHttpRequest(); var request = new XMLHttpRequest({ mozAnon: false });
if (!useBFF) { if (!useBFF) {
request.open("POST", url, true); request.open("POST", url, true);

View file

@ -6,6 +6,10 @@
// in non-window non-Worker context // in non-window non-Worker context
function run_test() { function run_test() {
Services.prefs.setBoolPref(
"network.fetch.systemDefaultsToOmittingCredentials",
false
);
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("GET", "data:,", false); xhr.open("GET", "data:,", false);
var exceptionThrown = false; var exceptionThrown = false;
@ -13,6 +17,7 @@ function run_test() {
xhr.responseType = ""; xhr.responseType = "";
xhr.withCredentials = false; xhr.withCredentials = false;
} catch (e) { } catch (e) {
console.error(e);
exceptionThrown = true; exceptionThrown = true;
} }
Assert.equal(false, exceptionThrown); Assert.equal(false, exceptionThrown);

View file

@ -7,6 +7,14 @@ function run_test() {
Assert.ok(x.mozAnon); Assert.ok(x.mozAnon);
Assert.ok(x.mozSystem); Assert.ok(x.mozSystem);
x = new XMLHttpRequest();
Assert.ok(x.mozAnon);
Assert.ok(x.mozSystem);
Services.prefs.setBoolPref(
"network.fetch.systemDefaultsToOmittingCredentials",
false
);
x = new XMLHttpRequest(); x = new XMLHttpRequest();
Assert.ok(!x.mozAnon); Assert.ok(!x.mozAnon);
Assert.ok(x.mozSystem); Assert.ok(x.mozSystem);

View file

@ -32,9 +32,12 @@ dictionary MozXMLHttpRequestParameters
{ {
/** /**
* If true, the request will be sent without cookie and authentication * If true, the request will be sent without cookie and authentication
* headers. * headers. Defaults to true for system/privileged/chrome requests,
* and to false otherwise.
* Note that even if set to true, for system/privileged/chrome requests,
* manually-set 'Cookie' headers are not removed.
*/ */
boolean mozAnon = false; boolean mozAnon;
/** /**
* If true, the same origin policy will not be enforced on the request. * If true, the same origin policy will not be enforced on the request.

View file

@ -7,7 +7,9 @@
#include "XMLHttpRequest.h" #include "XMLHttpRequest.h"
#include "XMLHttpRequestMainThread.h" #include "XMLHttpRequestMainThread.h"
#include "XMLHttpRequestWorker.h" #include "XMLHttpRequestWorker.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Logging.h" #include "mozilla/Logging.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/net/CookieJarSettings.h" #include "mozilla/net/CookieJarSettings.h"
mozilla::LazyLogModule gXMLHttpRequestLog("XMLHttpRequest"); mozilla::LazyLogModule gXMLHttpRequestLog("XMLHttpRequest");
@ -21,15 +23,16 @@ already_AddRefed<XMLHttpRequest> XMLHttpRequest::Constructor(
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
nsCOMPtr<nsIGlobalObject> global = nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(aGlobal.GetAsSupports()); do_QueryInterface(aGlobal.GetAsSupports());
nsCOMPtr<nsIScriptObjectPrincipal> principal = nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
do_QueryInterface(aGlobal.GetAsSupports()); do_QueryInterface(aGlobal.GetAsSupports());
if (!global || !principal) { if (!global || !scriptPrincipal) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return nullptr;
} }
nsCOMPtr<nsICookieJarSettings> cookieJarSettings; nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global); nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global);
nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
if (window) { if (window) {
Document* document = window->GetExtantDoc(); Document* document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) { if (NS_WARN_IF(!document)) {
@ -40,13 +43,21 @@ already_AddRefed<XMLHttpRequest> XMLHttpRequest::Constructor(
cookieJarSettings = document->CookieJarSettings(); cookieJarSettings = document->CookieJarSettings();
} else { } else {
// We are here because this is a sandbox. // We are here because this is a sandbox.
cookieJarSettings = cookieJarSettings = net::CookieJarSettings::Create(principal);
net::CookieJarSettings::Create(principal->GetPrincipal());
} }
RefPtr<XMLHttpRequestMainThread> req = new XMLHttpRequestMainThread(global); RefPtr<XMLHttpRequestMainThread> req = new XMLHttpRequestMainThread(global);
req->Construct(principal->GetPrincipal(), cookieJarSettings, false); req->Construct(principal, cookieJarSettings, false);
req->InitParameters(aParams.mMozAnon, aParams.mMozSystem);
bool isAnon = false;
if (aParams.mMozAnon.WasPassed()) {
isAnon = aParams.mMozAnon.Value();
} else {
isAnon =
StaticPrefs::network_fetch_systemDefaultsToOmittingCredentials() &&
(aParams.mMozSystem || principal->IsSystemPrincipal());
}
req->InitParameters(isAnon, aParams.mMozSystem);
return req.forget(); return req.forget();
} }

View file

@ -1388,10 +1388,12 @@ already_AddRefed<XMLHttpRequest> XMLHttpRequestWorker::Construct(
new XMLHttpRequestWorker(workerPrivate, global); new XMLHttpRequestWorker(workerPrivate, global);
if (workerPrivate->XHRParamsAllowed()) { if (workerPrivate->XHRParamsAllowed()) {
if (aParams.mMozSystem) if (aParams.mMozSystem) {
xhr->mMozAnon = true; xhr->mMozAnon = true;
else } else {
xhr->mMozAnon = aParams.mMozAnon; xhr->mMozAnon =
aParams.mMozAnon.WasPassed() ? aParams.mMozAnon.Value() : false;
}
xhr->mMozSystem = aParams.mMozSystem; xhr->mMozSystem = aParams.mMozSystem;
} }

View file

@ -12,7 +12,7 @@ var { promiseDocumentLoaded } = ExtensionUtils;
const checkRedirected = (url, redirectURI) => { const checkRedirected = (url, redirectURI) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest({ mozAnon: false });
xhr.open("GET", url); xhr.open("GET", url);
// We expect this if the user has not authenticated. // We expect this if the user has not authenticated.
xhr.onload = () => { xhr.onload = () => {

View file

@ -33,7 +33,7 @@ export class NetworkManager {
this.getXhr = this.getXhr =
args.getXhr || args.getXhr ||
function NetworkManager_getXhr() { function NetworkManager_getXhr() {
return new XMLHttpRequest(); return new XMLHttpRequest({ mozAnon: false });
}; };
this.currXhrId = 0; this.currXhrId = 0;

View file

@ -545,7 +545,7 @@ class RangedChromeActions extends ChromeActions {
} }
}; };
var getXhr = function getXhr() { var getXhr = function getXhr() {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest({ mozAnon: false });
xhr.addEventListener("readystatechange", xhr_onreadystatechange); xhr.addEventListener("readystatechange", xhr_onreadystatechange);
return xhr; return xhr;
}; };

View file

@ -273,7 +273,7 @@ export var ReaderMode = {
"READER_MODE_DOWNLOAD_RESULT" "READER_MODE_DOWNLOAD_RESULT"
); );
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest({ mozAnon: false });
xhr.open("GET", url, true); xhr.open("GET", url, true);
xhr.onerror = evt => reject(evt.error); xhr.onerror = evt => reject(evt.error);
xhr.responseType = docContentType === "text/plain" ? "text" : "document"; xhr.responseType = docContentType === "text/plain" ? "text" : "document";

View file

@ -135,7 +135,7 @@ function submitToServer(data) {
tool: "asan-nightly-program", tool: "asan-nightly-program",
}; };
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest({ mozAnon: !auth_token });
xhr.open("POST", api_url, true); xhr.open("POST", api_url, true);
xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Content-Type", "application/json");