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:
Bogdan Tara 2019-06-06 23:13:52 +03:00
parent 7c3448ffb3
commit bde97b25f5
14 changed files with 58 additions and 262 deletions

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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");
}

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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();

View File

@ -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(

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,