Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2024-01-11 09:52:46 +08:00
commit 80c4f1d745
79 changed files with 1353 additions and 509 deletions

View file

@ -59,6 +59,7 @@
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SRILogHelper.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/UniquePtr.h"
#include "Principal.h"
#include "WorkerHolder.h"
@ -112,7 +113,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
const nsAString& aScriptURL,
bool aIsMainScript,
WorkerScriptType aWorkerScriptType,
nsContentPolicyType aContentPolicyType,
nsContentPolicyType aMainScriptContentPolicyType,
nsLoadFlags aLoadFlags,
bool aDefaultURIEncoding,
nsIChannel** aChannel)
@ -169,6 +170,10 @@ ChannelFromScriptURL(nsIPrincipal* principal,
secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
}
nsContentPolicyType contentPolicyType =
aIsMainScript ? aMainScriptContentPolicyType
: nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS;
nsCOMPtr<nsIChannel> channel;
// If we have the document, use it. Unfortunately, for dedicated workers
// 'parentDoc' ends up being the parent document, which is not the document
@ -179,7 +184,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
uri,
parentDoc,
secFlags,
aContentPolicyType,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
aLoadFlags,
@ -194,7 +199,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
uri,
principal,
secFlags,
aContentPolicyType,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
aLoadFlags,
@ -464,6 +469,8 @@ private:
nsCOMPtr<nsIURI> mBaseURI;
mozilla::dom::ChannelInfo mChannelInfo;
UniquePtr<PrincipalInfo> mPrincipalInfo;
nsCString mCSPHeaderValue;
nsCString mCSPReportOnlyHeaderValue;
};
NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver)
@ -657,6 +664,34 @@ private:
ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
// Checking the MIME type is only required for ServiceWorkers'
// importScripts, per step 10 of https://w3c.github.io/ServiceWorker/#importscripts
//
// "Extract a MIME type from the response’s header list. If this MIME type
// (ignoring parameters) is not a JavaScript MIME type, return a network error."
if (mWorkerPrivate->IsServiceWorker()) {
nsAutoCString mimeType;
channel->GetContentType(mimeType);
if (!nsContentUtils::IsJavascriptMIMEType(NS_ConvertUTF8toUTF16(mimeType))) {
const nsCString& scope =
mWorkerPrivate->ServiceWorkerScope();
ServiceWorkerManager::LocalizeAndReportToAllClients(
scope, "ServiceWorkerRegisterMimeTypeError2",
nsTArray<nsString> {
NS_ConvertUTF8toUTF16(scope),
NS_ConvertUTF8toUTF16(mimeType),
loadInfo.mURL
}
);
channel->Cancel(NS_ERROR_DOM_NETWORK_ERR);
return NS_ERROR_DOM_NETWORK_ERR;
}
}
MOZ_ASSERT(channel == loadInfo.mChannel);
// We synthesize the result code, but its never exposed to content.
@ -691,6 +726,7 @@ private:
}
ir->SetPrincipalInfo(Move(principalInfo));
ir->Headers()->FillResponseHeaders(loadInfo.mChannel);
RefPtr<mozilla::dom::Response> response =
new mozilla::dom::Response(mCacheCreator->Global(), ir, nullptr);
@ -1127,11 +1163,11 @@ private:
("Scriptloader::Load, SRI required but not supported in workers"));
nsCOMPtr<nsIContentSecurityPolicy> wcsp;
chanLoadInfo->LoadingPrincipal()->GetCsp(getter_AddRefs(wcsp));
MOZ_ASSERT(wcsp, "We sould have a CSP for the worker here");
MOZ_ASSERT(wcsp, "We should have a CSP for the worker here");
if (wcsp) {
wcsp->LogViolationDetails(
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
aLoadInfo.mURL, EmptyString(), 0, EmptyString(), EmptyString());
aLoadInfo.mURL, EmptyString(), 0, 0, EmptyString(), EmptyString());
}
return NS_ERROR_SRI_CORRUPT;
}
@ -1199,53 +1235,14 @@ private:
// load group's appId and browser element flag.
MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(channelLoadGroup, channelPrincipal));
mWorkerPrivate->SetPrincipal(channelPrincipal, channelLoadGroup);
mWorkerPrivate->SetPrincipalOnMainThread(channelPrincipal, channelLoadGroup);
// We did inherit CSP in bug 1223647. If we do not already have a CSP, we
// should get it from the HTTP headers on the worker script.
if (!mWorkerPrivate->GetCSP() && CSPService::sCSPEnabled) {
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
MOZ_ASSERT(principal, "Should not be null");
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = principal->EnsureCSP(nullptr, getter_AddRefs(csp));
if (csp) {
// If there's a CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false);
NS_ENSURE_SUCCESS(rv, rv);
}
// If there's a report-only CSP header, apply it.
if (!cspROHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspROHeaderValue, true);
NS_ENSURE_SUCCESS(rv, rv);
}
// Set evalAllowed, default value is set in GetAllowsEval
bool evalAllowed = false;
bool reportEvalViolations = false;
rv = csp->GetAllowsEval(&reportEvalViolations, &evalAllowed);
NS_ENSURE_SUCCESS(rv, rv);
mWorkerPrivate->SetCSP(csp);
mWorkerPrivate->SetEvalAllowed(evalAllowed);
mWorkerPrivate->SetReportCSPViolations(reportEvalViolations);
// Set ReferrerPolicy, default value is set in GetReferrerPolicy
bool hasReferrerPolicy = false;
uint32_t rp = mozilla::net::RP_Default;
rv = csp->GetReferrerPolicy(&rp, &hasReferrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
if (hasReferrerPolicy) { //FIXME bug 1307366: move RP out of CSP code
mWorkerPrivate->SetReferrerPolicy(static_cast<net::ReferrerPolicy>(rp));
}
}
rv = mWorkerPrivate->SetCSPFromHeaderValues(tCspHeaderValue,
tCspROHeaderValue);
NS_ENSURE_SUCCESS(rv, rv);
}
if (parent) {
// XHR Params Allowed
@ -1270,7 +1267,9 @@ private:
DataReceivedFromCache(uint32_t aIndex, const uint8_t* aString,
uint32_t aStringLen,
const mozilla::dom::ChannelInfo& aChannelInfo,
UniquePtr<PrincipalInfo> aPrincipalInfo)
UniquePtr<PrincipalInfo> aPrincipalInfo,
const nsACString& aCSPHeaderValue,
const nsACString& aCSPReportOnlyHeaderValue)
{
AssertIsOnMainThread();
MOZ_ASSERT(aIndex < mLoadInfos.Length());
@ -1279,6 +1278,7 @@ private:
nsCOMPtr<nsIPrincipal> responsePrincipal =
PrincipalInfoToPrincipal(*aPrincipalInfo);
MOZ_DIAGNOSTIC_ASSERT(responsePrincipal);
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
if (!principal) {
@ -1306,17 +1306,35 @@ private:
mWorkerPrivate->SetBaseURI(finalURI);
}
mozilla::DebugOnly<nsIPrincipal*> principal = mWorkerPrivate->GetPrincipal();
MOZ_ASSERT(principal);
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
MOZ_ASSERT(loadGroup);
MOZ_DIAGNOSTIC_ASSERT(loadGroup);
mozilla::DebugOnly<bool> equal = false;
MOZ_ASSERT(responsePrincipal && NS_SUCCEEDED(responsePrincipal->Equals(principal, &equal)));
MOZ_ASSERT(equal);
#if defined(DEBUG)
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
MOZ_DIAGNOSTIC_ASSERT(principal);
bool equal = false;
MOZ_ALWAYS_SUCCEEDS(responsePrincipal->Equals(principal, &equal));
MOZ_DIAGNOSTIC_ASSERT(equal);
nsCOMPtr<nsIContentSecurityPolicy> csp;
MOZ_ALWAYS_SUCCEEDS(responsePrincipal->GetCsp(getter_AddRefs(csp)));
MOZ_DIAGNOSTIC_ASSERT(!csp);
#endif
mWorkerPrivate->InitChannelInfo(aChannelInfo);
mWorkerPrivate->SetPrincipal(responsePrincipal, loadGroup);
// Override the principal on the WorkerPrivate. We just asserted that
// this is the same as our current WorkerPrivate principal, so this is
// almost a no-op. We must do, it though, in order to avoid accidentally
// propagating the CSP object back to the ServiceWorkerRegistration
// principal. If bug 965637 is fixed then this can be removed.
rv = mWorkerPrivate->SetPrincipalOnMainThread(responsePrincipal, loadGroup);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
rv = mWorkerPrivate->SetCSPFromHeaderValues(aCSPHeaderValue,
aCSPReportOnlyHeaderValue);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
}
if (NS_SUCCEEDED(rv)) {
@ -1730,6 +1748,14 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
return;
}
InternalHeaders* headers = response->GetInternalHeaders();
IgnoredErrorResult ignored;
headers->Get(NS_LITERAL_CSTRING("content-security-policy"),
mCSPHeaderValue, ignored);
headers->Get(NS_LITERAL_CSTRING("content-security-policy-report-only"),
mCSPReportOnlyHeaderValue, ignored);
nsCOMPtr<nsIInputStream> inputStream;
response->GetBody(getter_AddRefs(inputStream));
mChannelInfo = response->GetChannelInfo();
@ -1741,7 +1767,8 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
if (!inputStream) {
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mChannelInfo,
Move(mPrincipalInfo));
Move(mPrincipalInfo), mCSPHeaderValue,
mCSPReportOnlyHeaderValue);
return;
}
@ -1801,7 +1828,8 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
MOZ_ASSERT(mPrincipalInfo);
mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mChannelInfo,
Move(mPrincipalInfo));
Move(mPrincipalInfo), mCSPHeaderValue,
mCSPReportOnlyHeaderValue);
return NS_OK;
}
@ -2170,7 +2198,7 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
nsIDocument* aParentDoc,
nsILoadGroup* aLoadGroup,
const nsAString& aScriptURL,
nsContentPolicyType aContentPolicyType,
nsContentPolicyType aMainScriptContentPolicyType,
bool aDefaultURIEncoding,
nsIChannel** aChannel)
{
@ -2183,8 +2211,9 @@ ChannelFromScriptURLMainThread(nsIPrincipal* aPrincipal,
return ChannelFromScriptURL(aPrincipal, aBaseURI, aParentDoc, aLoadGroup,
ios, secMan, aScriptURL, true, WorkerScript,
aContentPolicyType, nsIRequest::LOAD_NORMAL,
aDefaultURIEncoding, aChannel);
aMainScriptContentPolicyType,
nsIRequest::LOAD_NORMAL, aDefaultURIEncoding,
aChannel);
}
nsresult