зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1555050) for test_reloadInFreshProcess.html failures CLOSED TREE
Backed out changeset f5e954d593f8 (bug 1555050) Backed out changeset b5b99e78b753 (bug 1555050)
This commit is contained in:
Родитель
7c3448ffb3
Коммит
bde97b25f5
|
@ -6937,7 +6937,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
|
||||
LoadURIOptions loadURIOptions;
|
||||
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
|
||||
loadURIOptions.mCsp = loadInfo->GetCspToInherit();
|
||||
loadURIOptions.mCsp = loadInfo->GetCsp();
|
||||
loadURIOptions.mPostData = newPostData;
|
||||
return LoadURI(newSpecW, loadURIOptions);
|
||||
}
|
||||
|
@ -10061,16 +10061,16 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
|
|||
}
|
||||
}
|
||||
|
||||
// For document loads we store the CSP that potentially needs to
|
||||
// be inherited by the new document, e.g. in case we are loading
|
||||
// an opaque origin like a data: URI. The actual inheritance
|
||||
// check happens within Document::InitCSP().
|
||||
// Please create an actual copy of the CSP (do not share the same
|
||||
// reference) otherwise a Meta CSP of an opaque origin will
|
||||
// incorrectly be propagated to the embedding document.
|
||||
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
|
||||
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(csp.get()));
|
||||
loadInfo->SetCSPToInherit(cspToInherit);
|
||||
if (CSP_ShouldResponseInheritCSP(channel)) {
|
||||
// If the new load needs to inherit the CSP, temporarily store the CSP
|
||||
// on the loadinfo, and transfer it to the new Document within
|
||||
// Document::InitCSP(). Please create an actual copy of the CSP (do not
|
||||
// share the same reference) otherwise a Meta CSP of an opaque origin
|
||||
// will incorrectly be propagated to the embedding document.
|
||||
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
|
||||
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(csp.get()));
|
||||
loadInfo->SetCSPToInherit(cspToInherit);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
||||
|
@ -11471,7 +11471,7 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
|||
triggeringPrincipal = loadInfo->TriggeringPrincipal();
|
||||
}
|
||||
if (!csp) {
|
||||
csp = loadInfo->GetCspToInherit();
|
||||
csp = static_cast<net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
|
||||
}
|
||||
|
||||
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
|
||||
|
|
|
@ -2951,15 +2951,12 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
|
|||
|
||||
MOZ_ASSERT(!mCSP, "where did mCSP get set if not here?");
|
||||
|
||||
// If there is a CSP that needs to be inherited from whatever
|
||||
// global is considered the client of the document fetch then
|
||||
// we query it here from the loadinfo in case the newly created
|
||||
// document needs to inherit the CSP. See:
|
||||
// https://w3c.github.io/webappsec-csp/#initialize-document-csp
|
||||
if (CSP_ShouldResponseInheritCSP(aChannel)) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
mCSP = loadInfo->GetCspToInherit();
|
||||
}
|
||||
// If there is a CSP that needs to be inherited either from the
|
||||
// embedding doc or from the opening doc, then we query it here
|
||||
// from the loadinfo because the docshell temporarily stored it
|
||||
// on the loadinfo so we can set it here.
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
mCSP = static_cast<net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
|
||||
|
||||
// If there is no CSP to inherit, then we create a new CSP here so
|
||||
// that history entries always have the right reference in case a
|
||||
|
|
|
@ -9505,7 +9505,7 @@ bool nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel) {
|
|||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal = loadInfo->TriggeringPrincipal();
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCspToInherit();
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCsp();
|
||||
|
||||
// Get the channel's load flags, and use them to generate nsIWebNavigation
|
||||
// load flags. We want to make sure to propagate the refresh and cache busting
|
||||
|
|
|
@ -161,7 +161,8 @@ nsresult nsJSThunk::EvaluateScript(
|
|||
// CSP check: javascript: URIs disabled unless "inline" scripts are
|
||||
// allowed. Here we use the CSP of the thing that started the load,
|
||||
// which is the CSPToInherit of the loadInfo.
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCspToInherit();
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp =
|
||||
static_cast<mozilla::net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
|
||||
if (csp) {
|
||||
bool allowsInlineScript = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const TESTFRAME_QUERY_LARGE_ALLOCATION_WITH_NO_CSP =
|
||||
`<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1555050 - Test CSP Navigation using ReloadInFreshProcess</title>
|
||||
</head>
|
||||
<body>
|
||||
testframe<br/>
|
||||
<script>
|
||||
// we have to use noopener otherwise the window is not the only window in the tabgroup which is needed
|
||||
// for "Large-Allocation" to succeed
|
||||
window.open("http://test1.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?largeAllocation_with_no_csp", "_blank", "noopener");
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const TESTFRAME_QUERY_LARGE_ALLOCATION_WITH_CSP =
|
||||
`<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1555050 - Test CSP Navigation using ReloadInFreshProcess</title>
|
||||
</head>
|
||||
<body>
|
||||
testframe<br/>
|
||||
<script>
|
||||
// we have to use noopener otherwise the window is not the only window in the tabgroup which is needed
|
||||
// for "Large-Allocation" to succeed
|
||||
window.open("http://test2.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?largeAllocation_with_csp", "_blank", "noopener");
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const LARGE_ALLOCATION =
|
||||
`<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1555050 - Test CSP Navigation using ReloadInFreshProcess</title>
|
||||
</head>
|
||||
<body>
|
||||
largeAllocation<br/>
|
||||
<script>
|
||||
window.close();
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
var queryString = request.queryString;
|
||||
|
||||
if (queryString == "testframe_with_csp") {
|
||||
response.setHeader("Content-Security-Policy", "upgrade-insecure-requests", false);
|
||||
response.write(TESTFRAME_QUERY_LARGE_ALLOCATION_WITH_NO_CSP);
|
||||
return;
|
||||
}
|
||||
|
||||
if (queryString == "testframe_with_no_csp") {
|
||||
response.write(TESTFRAME_QUERY_LARGE_ALLOCATION_WITH_CSP);
|
||||
return;
|
||||
}
|
||||
|
||||
if (queryString == "largeAllocation_with_csp") {
|
||||
response.setHeader("Content-Security-Policy", "upgrade-insecure-requests", false);
|
||||
response.setHeader("Large-Allocation", "0", false);
|
||||
response.write(LARGE_ALLOCATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (queryString == "largeAllocation_with_no_csp") {
|
||||
response.setHeader("Large-Allocation", "0", false);
|
||||
response.write(LARGE_ALLOCATION);
|
||||
return;
|
||||
}
|
||||
|
||||
// we should never get here, but just in case return something unexpected
|
||||
response.write("do'h");
|
||||
}
|
|
@ -379,7 +379,3 @@ support-files =
|
|||
support-files =
|
||||
file_script_template.html
|
||||
file_script_template.js
|
||||
[test_reloadInFreshProcess.html]
|
||||
skip-if = os == 'win' && bits == 32
|
||||
support-files =
|
||||
file_reloadInFreshProcess.sjs
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1555050: Test CSP Navigation using ReloadInFreshProcess</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe style="width:100%;" id="testframe_with_csp"></iframe>
|
||||
<iframe style="width:100%;" id="testframe_with_no_csp"></iframe>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/*
|
||||
* Description of the tests:
|
||||
*
|
||||
* | Frame | Large Allocation Window | Result
|
||||
* -----------------------------------------------------------------------------
|
||||
* Test 1 | "upgrade-insecure-requests" | | https
|
||||
* Test 2 | | "upgrade-insecure-requests" | http
|
||||
*
|
||||
* Test 1:
|
||||
* We load an iframe which uses 'upgrade-insecure-requests' which then
|
||||
* opens an "http" window which uses the header "Large-Allocation".
|
||||
* We observe that the initial request as well as the "Large-Allocation"
|
||||
* request get upgraded to use "https://test1.example.com".
|
||||
*
|
||||
* Test 2:
|
||||
* We load an iframe which does not use any CSP and opens an "http" window
|
||||
* which uses the header "Large-Allocation" as well as a CSP of
|
||||
* "upgrade-insecure-requests". We observe that both requests do
|
||||
* not get upgraded to https but still use "http://test2.example.com".
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let httpsCounter = 0;
|
||||
let httpCounter = 0;
|
||||
|
||||
function checkTestComplete() {
|
||||
if (httpsCounter == 2 && httpCounter == 2) {
|
||||
ok(true, "Frame with CSP caused upgrade; Frame with no CSP caused no upgrade");
|
||||
window.URLExaminer.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
if (data === "https://test1.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?largeAllocation_with_no_csp") {
|
||||
httpsCounter++;
|
||||
checkTestComplete();
|
||||
return;
|
||||
}
|
||||
if (data === "http://test2.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?largeAllocation_with_csp") {
|
||||
httpCounter++;
|
||||
checkTestComplete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
window.URLExaminer = new examiner();
|
||||
|
||||
function runTest() {
|
||||
let testframe_with_csp = document.getElementById("testframe_with_csp");
|
||||
testframe_with_csp.src = "http://test1.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?testframe_with_csp";
|
||||
|
||||
let testframe_with_no_csp = document.getElementById("testframe_with_no_csp");
|
||||
testframe_with_no_csp.src = "http://test2.example.com/tests/dom/security/test/csp/file_reloadInFreshProcess.sjs?testframe_with_no_csp";
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.largeAllocation.forceEnable", true]]}, runTest);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1702,8 +1702,27 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
|
|||
return rv;
|
||||
}
|
||||
|
||||
info.mPrincipal = mInfo->Principal();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = mInfo->Principal()->GetURI(getter_AddRefs(uri));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!uri)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create a pristine codebase principal to avoid any possibility of inheriting
|
||||
// CSP values. The principal on the registration may be polluted with CSP
|
||||
// from the registering page or other places the principal is passed. If
|
||||
// bug 965637 is ever fixed this can be removed.
|
||||
info.mPrincipal =
|
||||
BasePrincipal::CreateCodebasePrincipal(uri, mInfo->GetOriginAttributes());
|
||||
if (NS_WARN_IF(!info.mPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
info.mLoadingPrincipal = info.mPrincipal;
|
||||
|
||||
// StoragePrincipal for ServiceWorkers is equal to mPrincipal because, at the
|
||||
// moment, ServiceWorkers are not exposed in partitioned contexts.
|
||||
info.mStoragePrincipal = info.mPrincipal;
|
||||
|
|
|
@ -237,8 +237,6 @@ nsresult WorkerLoadInfo::SetPrincipalsAndCSPFromChannel(nsIChannel* aChannel) {
|
|||
getter_AddRefs(loadGroup));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Workers themselves can have their own CSP - Workers of an opaque origin
|
||||
// however inherit the CSP of the document that spawned the worker.
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
if (CSP_ShouldResponseInheritCSP(aChannel)) {
|
||||
nsCOMPtr<nsILoadInfo> loadinfo = aChannel->LoadInfo();
|
||||
|
|
|
@ -547,7 +547,7 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
|
|||
|
||||
Maybe<CSPInfo> maybeCspToInheritInfo;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit =
|
||||
aLoadInfo->GetCspToInherit();
|
||||
static_cast<net::LoadInfo*>(aLoadInfo)->GetCSPToInherit();
|
||||
if (cspToInherit) {
|
||||
CSPInfo cspToInheritInfo;
|
||||
Unused << NS_WARN_IF(
|
||||
|
|
|
@ -1484,10 +1484,5 @@ already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetPreloadCsp() {
|
|||
return preloadCSP.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
|
||||
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit = mCspToInherit;
|
||||
return cspToInherit.forget();
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -91,30 +91,21 @@ class LoadInfo final : public nsILoadInfo {
|
|||
void SetIsFromProcessingFrameAttributes();
|
||||
|
||||
// Hands off from the cspToInherit functionality!
|
||||
//
|
||||
// For navigations, GetCSPToInherit returns what the spec calls the
|
||||
// "request's client's global object's CSP list", or more precisely
|
||||
// a snapshot of it taken when the navigation starts. For navigations
|
||||
// that need to inherit their CSP, this is the right CSP to use for
|
||||
// the new document. We need a way to transfer the CSP from the
|
||||
// docshell (where the navigation starts) to the point where the new
|
||||
// document is created and decides whether to inherit its CSP, and
|
||||
// this is the mechanism we use for that.
|
||||
//
|
||||
// For example:
|
||||
// A document with a CSP triggers a new top-level data: URI load.
|
||||
// We pass the CSP of the document that triggered the load all the
|
||||
// way to docshell. Within docshell we call SetCSPToInherit() on the
|
||||
// loadinfo. Within Document::InitCSP() we check if the newly created
|
||||
// document needs to inherit the CSP. If so, we call GetCSPToInherit()
|
||||
// and set the inherited CSP as the CSP for the new document. Please
|
||||
// note that any additonal Meta CSP in that document will be merged
|
||||
// into that CSP. Any subresource loads within that document
|
||||
// subesquently will receive the correct CSP by querying
|
||||
// loadinfo->GetCSP() from that point on.
|
||||
// The only place that knows that a new document load needs to inherit the
|
||||
// CSP is the docshell. At that point neither the document nor the client
|
||||
// are available yet. Since we need a way to transfer the CSP from the
|
||||
// docshell to the document, we temporarily store the CSP that needs to
|
||||
// be inherited within the Loadinfo. In other words, those two functions
|
||||
// build the bridge to transfer the CSP from the docshell into the doc.
|
||||
void SetCSPToInherit(nsIContentSecurityPolicy* aCspToInherit) {
|
||||
mCspToInherit = aCspToInherit;
|
||||
}
|
||||
// Certain schemes need to inherit the CSP. If needed, we temporarily
|
||||
// store the CSP from the embedding/opening document here which then
|
||||
// gets propagated to the new doc within Document::InitCSP(). This
|
||||
// member is only ever non-null if the new doc actually needs to
|
||||
// inherit the CSP from the embedding/opening document.
|
||||
nsIContentSecurityPolicy* GetCSPToInherit() { return mCspToInherit; }
|
||||
|
||||
private:
|
||||
// private constructor that is only allowed to be called from within
|
||||
|
|
|
@ -1027,46 +1027,11 @@ interface nsILoadInfo : nsISupports
|
|||
PerformanceStoragePtr GetPerformanceStorage();
|
||||
|
||||
/**
|
||||
* Returns the CSP (or Preload CSP for preloads) which should be enforced
|
||||
* when fetching the resource this loadinfo belongs to.
|
||||
*
|
||||
* a) Non-navigations:
|
||||
* For non-navigation loads, GetCSP() returns what the spec refers to as the
|
||||
* "request's client's global object's CSP list". In practice, if this is the
|
||||
* loadinfo of a subresource load (e.g an image load), then GetCSP() or
|
||||
* GetPreloadCSP() returns the CSP of the document which embeds the image.
|
||||
* The returned CSP includes any policy delivered through the HTTP header or
|
||||
* also through the meta tag (modulo the difference for preloads, e.g. image
|
||||
* preloads have to query GetPreloadCsp() because at the time of preloading
|
||||
* we are not entirely sure if the Meta CSP will be applied to the document
|
||||
* in the end or not). Please note that GetCSPToInherit() called on a
|
||||
* loadinfo for any non-navigation always returns null.
|
||||
*
|
||||
* b) Navigations:
|
||||
* * Top-level loads:
|
||||
* For top-level loads (navigations) GetCSP() will return null, unless
|
||||
* the navigation is started by a WebExtension, in which case it will
|
||||
* return the CSP of the webextension, if any.
|
||||
* If you need to query the CSP that potentially should apply to the
|
||||
* new top-level load, you have to query GetCspToInherit(), which is
|
||||
* the CSP of the request's client's global object, just like GetCsp()
|
||||
* is for non-navigation requests.
|
||||
*
|
||||
* * Iframe-loads:
|
||||
* For iframe-loads (navigations) GetCSP() will return the CSP of the
|
||||
* parent document, unless the navigation is started by a WebExtension,
|
||||
* in which case it will return the CSP of the webextension, if any.
|
||||
*
|
||||
* If you need to query the CSP that should potentially be inherited
|
||||
* into the new document, you have to query GetCSPToInherit().
|
||||
*
|
||||
* TODO Bug 1557114:
|
||||
* After evaluating what CSP to use for frame navigations we should
|
||||
* update the above documentation to match the outcome of Bug 1557114.
|
||||
* Query the CSP (or Preload CSP for preloads) which should be
|
||||
* enforced for the channel this loadinfo belongs to.
|
||||
*/
|
||||
[notxpcom,nostdcall] CSPRef GetCsp();
|
||||
[notxpcom,nostdcall] CSPRef GetPreloadCsp();
|
||||
[notxpcom,nostdcall] CSPRef GetCspToInherit();
|
||||
|
||||
/**
|
||||
* The service worker and fetch specifications require returning the
|
||||
|
|
|
@ -73,8 +73,8 @@ interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2
|
|||
* @param aDocShell
|
||||
* The docshell performing the load.
|
||||
* @param aCsp
|
||||
* The CSP to be used for reloading the top-level load. That is the CSP
|
||||
* of the document that initially triggered the new document load.
|
||||
* The CSP to be used for that load. That is the CSP that e.g. upgrades
|
||||
* the load to HTTPS in case upgrade-insecure-requests is set.
|
||||
*/
|
||||
bool reloadInFreshProcess(in nsIDocShell aDocShell,
|
||||
in nsIURI aURI,
|
||||
|
|
Загрузка…
Ссылка в новой задаче