diff options
Diffstat (limited to 'docshell/base')
-rw-r--r-- | docshell/base/moz.build | 3 | ||||
-rw-r--r-- | docshell/base/nsAboutRedirector.cpp | 40 | ||||
-rw-r--r-- | docshell/base/nsDSURIContentListener.cpp | 86 | ||||
-rw-r--r-- | docshell/base/nsDSURIContentListener.h | 21 | ||||
-rw-r--r-- | docshell/base/nsDocShell.cpp | 51 | ||||
-rw-r--r-- | docshell/base/nsIRefreshURI.idl | 15 |
6 files changed, 137 insertions, 79 deletions
diff --git a/docshell/base/moz.build b/docshell/base/moz.build index 1eb04c227..6ea3e6d28 100644 --- a/docshell/base/moz.build +++ b/docshell/base/moz.build @@ -81,8 +81,5 @@ LOCAL_INCLUDES += [ if CONFIG['MOZ_TOOLKIT_SEARCH']: DEFINES['MOZ_TOOLKIT_SEARCH'] = True -if CONFIG['MOZ_DEVTOOLS'] == 'all': - DEFINES['MOZ_DEVTOOLS_ALL'] = True - if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wno-error=shadow'] diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index f300e0ce2..e56447296 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -41,22 +41,21 @@ static RedirEntry kRedirMap[] = { }, { "buildconfig", "chrome://global/content/buildconfig.html", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::MAKE_LINKABLE }, { "checkerboard", "chrome://global/content/aboutCheckerboard.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::ALLOW_SCRIPT + nsIAboutModule::ALLOW_SCRIPT }, { "config", "chrome://global/content/config.xul", 0 }, -#ifdef MOZ_CRASHREPORTER - { "crashes", "chrome://global/content/crashes.xhtml", 0 }, -#endif { - "credits", "https://www.mozilla.org/credits/", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + "credits", "http://www.palemoon.org/Contributors.shtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::MAKE_LINKABLE }, -#ifdef MOZ_DEVTOOLS_ALL +#ifdef MOZ_DEVTOOLS { "debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml", nsIAboutModule::ALLOW_SCRIPT @@ -65,7 +64,7 @@ static RedirEntry kRedirMap[] = { { "license", "chrome://global/content/license.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::MAKE_LINKABLE + nsIAboutModule::MAKE_LINKABLE }, { "logo", "chrome://branding/content/about.png", @@ -73,6 +72,13 @@ static RedirEntry kRedirMap[] = { // Linkable for testing reasons. nsIAboutModule::MAKE_LINKABLE }, +#ifdef MOZ_PHOENIX + { + "logopage", "chrome://global/content/logopage.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, +#endif { "memory", "chrome://global/content/aboutMemory.xhtml", nsIAboutModule::ALLOW_SCRIPT @@ -84,9 +90,9 @@ static RedirEntry kRedirMap[] = { { "neterror", "chrome://global/content/netError.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::URI_CAN_LOAD_IN_CHILD | - nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT + nsIAboutModule::URI_CAN_LOAD_IN_CHILD | + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT }, { "networking", "chrome://global/content/aboutNetworking.xhtml", @@ -95,7 +101,7 @@ static RedirEntry kRedirMap[] = { { "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT + nsIAboutModule::HIDE_FROM_ABOUTABOUT }, { "performance", "chrome://global/content/aboutPerformance.xhtml", @@ -122,10 +128,10 @@ static RedirEntry kRedirMap[] = { { "srcdoc", "about:blank", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT | - // Needs to be linkable so content can touch its own srcdoc frames - nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::URI_CAN_LOAD_IN_CHILD + nsIAboutModule::HIDE_FROM_ABOUTABOUT | + // Needs to be linkable so content can touch its own srcdoc frames + nsIAboutModule::MAKE_LINKABLE | + nsIAboutModule::URI_CAN_LOAD_IN_CHILD }, { "support", "chrome://global/content/aboutSupport.xhtml", diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp index cfac54f7f..93ce3cb26 100644 --- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -22,6 +22,7 @@ #include "nsIScriptError.h" #include "nsDocShellLoadTypes.h" #include "nsIMultiPartChannel.h" +#include "mozilla/dom/nsCSPUtils.h" using namespace mozilla; @@ -84,14 +85,6 @@ nsDSURIContentListener::DoContent(const nsACString& aContentType, NS_ENSURE_ARG_POINTER(aContentHandler); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); - // Check whether X-Frame-Options permits us to load this content in an - // iframe and abort the load (unless we've disabled x-frame-options - // checking). - if (!CheckFrameOptions(aRequest)) { - *aAbortProcess = true; - return NS_OK; - } - *aAbortProcess = false; // determine if the channel has just been retargeted to us... @@ -265,9 +258,10 @@ nsDSURIContentListener::SetParentContentListener( return NS_OK; } -bool +/* static */ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, - const nsAString& aPolicy) + const nsAString& aPolicy, + nsIDocShell* aDocShell) { static const char allowFrom[] = "allow-from"; const uint32_t allowFromLen = ArrayLength(allowFrom) - 1; @@ -285,7 +279,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, aHttpChannel->GetURI(getter_AddRefs(uri)); // XXXkhuey when does this happen? Is returning true safe here? - if (!mDocShell) { + if (!aDocShell) { return true; } @@ -293,7 +287,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, // window, if we're not the top. X-F-O: SAMEORIGIN requires that the // document must be same-origin with top window. X-F-O: DENY requires that // the document must never be framed. - nsCOMPtr<nsPIDOMWindowOuter> thisWindow = mDocShell->GetWindow(); + nsCOMPtr<nsPIDOMWindowOuter> thisWindow = aDocShell->GetWindow(); // If we don't have DOMWindow there is no risk of clickjacking if (!thisWindow) { return true; @@ -313,7 +307,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, // content-type docshell doesn't work because some chrome documents are // loaded in content docshells (see bug 593387). nsCOMPtr<nsIDocShellTreeItem> thisDocShellItem( - do_QueryInterface(static_cast<nsIDocShell*>(mDocShell))); + do_QueryInterface(static_cast<nsIDocShell*>(aDocShell))); nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem; nsCOMPtr<nsIDocShellTreeItem> curDocShellItem = thisDocShellItem; nsCOMPtr<nsIDocument> topDoc; @@ -402,22 +396,66 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, return true; } +// Ignore x-frame-options if CSP with frame-ancestors exists +static bool +ShouldIgnoreFrameOptions(nsIChannel* aChannel, nsIPrincipal* aPrincipal) +{ + NS_ENSURE_TRUE(aChannel, false); + NS_ENSURE_TRUE(aPrincipal, false); + + nsCOMPtr<nsIContentSecurityPolicy> csp; + aPrincipal->GetCsp(getter_AddRefs(csp)); + if (!csp) { + // if there is no CSP, then there is nothing to do here + return false; + } + + bool enforcesFrameAncestors = false; + csp->GetEnforcesFrameAncestors(&enforcesFrameAncestors); + if (!enforcesFrameAncestors) { + // if CSP does not contain frame-ancestors, then there + // is nothing to do here. + return false; + } + + // log warning to console that xfo is ignored because of CSP + nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); + uint64_t innerWindowID = loadInfo ? loadInfo->GetInnerWindowID() : 0; + const char16_t* params[] = { u"x-frame-options", + u"frame-ancestors" }; + CSP_LogLocalizedStr(u"IgnoringSrcBecauseOfDirective", + params, ArrayLength(params), + EmptyString(), // no sourcefile + EmptyString(), // no scriptsample + 0, // no linenumber + 0, // no columnnumber + nsIScriptError::warningFlag, + "CSP", innerWindowID); + + return true; +} + // Check if X-Frame-Options permits this document to be loaded as a subdocument. // This will iterate through and check any number of X-Frame-Options policies // in the request (comma-separated in a header, multiple headers, etc). -bool -nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest) +/* static */ bool +nsDSURIContentListener::CheckFrameOptions(nsIChannel* aChannel, + nsIDocShell* aDocShell, + nsIPrincipal* aPrincipal) { - nsresult rv; - nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest); - if (!chan) { + if (!aChannel || !aDocShell) { return true; } - nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(chan); + if (ShouldIgnoreFrameOptions(aChannel, aPrincipal)) { + return true; + } + + nsresult rv; + nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel); if (!httpChannel) { // check if it is hiding in a multipart channel - rv = mDocShell->GetHttpChannel(chan, getter_AddRefs(httpChannel)); + rv = nsDocShell::Cast(aDocShell)->GetHttpChannel(aChannel, getter_AddRefs(httpChannel)); if (NS_FAILED(rv)) { return false; } @@ -442,11 +480,11 @@ nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest) nsCharSeparatedTokenizer tokenizer(xfoHeaderValue, ','); while (tokenizer.hasMoreTokens()) { const nsSubstring& tok = tokenizer.nextToken(); - if (!CheckOneFrameOptionsPolicy(httpChannel, tok)) { + if (!CheckOneFrameOptionsPolicy(httpChannel, tok, aDocShell)) { // cancel the load and display about:blank httpChannel->Cancel(NS_BINDING_ABORTED); - if (mDocShell) { - nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell)); + if (aDocShell) { + nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(aDocShell)); if (webNav) { webNav->LoadURI(u"about:blank", 0, nullptr, nullptr, nullptr); @@ -459,7 +497,7 @@ nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest) return true; } -void +/* static */ void nsDSURIContentListener::ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, nsIURI* aThisURI, XFOHeader aHeader) diff --git a/docshell/base/nsDSURIContentListener.h b/docshell/base/nsDSURIContentListener.h index f33d1c045..432813471 100644 --- a/docshell/base/nsDSURIContentListener.h +++ b/docshell/base/nsDSURIContentListener.h @@ -28,6 +28,12 @@ public: nsresult Init(); + // Determine if X-Frame-Options allows content to be framed + // as a subdocument + static bool CheckFrameOptions(nsIChannel* aChannel, + nsIDocShell* aDocShell, + nsIPrincipal* aPrincipal); + protected: explicit nsDSURIContentListener(nsDocShell* aDocShell); virtual ~nsDSURIContentListener(); @@ -39,12 +45,9 @@ protected: mExistingJPEGStreamListener = nullptr; } - // Determine if X-Frame-Options allows content to be framed - // as a subdocument - bool CheckFrameOptions(nsIRequest* aRequest); - bool CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, - const nsAString& aPolicy); - + static bool CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, + const nsAString& aPolicy, + nsIDocShell* aDocShell); enum XFOHeader { eDENY, @@ -52,9 +55,9 @@ protected: eALLOWFROM }; - void ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, - nsIURI* aThisURI, - XFOHeader aHeader); + static void ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, + nsIURI* aThisURI, + XFOHeader aHeader); protected: nsDocShell* mDocShell; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ab119a016..58c182cbb 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2289,13 +2289,6 @@ nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) NS_IMETHODIMP nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) { -#ifdef MOZ_CRASHREPORTER - if (aUseRemoteTabs) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"), - NS_LITERAL_CSTRING("1")); - } -#endif - mUseRemoteTabs = aUseRemoteTabs; return NS_OK; } @@ -6806,9 +6799,17 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsI */ loadInfo->SetReferrer(mCurrentURI); - /* Don't ever "guess" on which principal to use to avoid picking - * the current principal. - */ + // Set the triggering pricipal to aPrincipal if available, or current + // document's principal otherwise. + nsCOMPtr<nsIPrincipal> principal = aPrincipal; + if (!principal) { + nsCOMPtr<nsIDocument> doc = GetDocument(); + if (!doc) { + return NS_ERROR_FAILURE; + } + principal = doc->NodePrincipal(); + } + loadInfo->SetTriggeringPrincipal(principal); loadInfo->SetPrincipalIsExplicit(true); /* Check if this META refresh causes a redirection @@ -6836,13 +6837,6 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsI loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh); } - // If the principal is null, the refresh will have a triggeringPrincipal - // derived from the referrer URI, or will be set to the system principal - // if there is no refererrer. See LoadURI() - if (aPrincipal) { - loadInfo->SetTriggeringPrincipal(aPrincipal); - } - /* * LoadURI(...) will cancel all refresh timers... This causes the * Timer and its refreshData instance to be released... @@ -11025,6 +11019,29 @@ nsDocShell::DoURILoad(nsIURI* aURI, } } + // Navigational requests that are same origin need to be upgraded in case + // upgrade-insecure-requests is present. Please note that in that case + // the triggeringPrincipal is holding the CSP that potentially + // holds upgrade-insecure-requests. + nsCOMPtr<nsIContentSecurityPolicy> csp; + aTriggeringPrincipal->GetCsp(getter_AddRefs(csp)); + if (csp) { + bool upgradeInsecureRequests = false; + csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests); + if (upgradeInsecureRequests) { + // only upgrade if the navigation is same origin + nsCOMPtr<nsIPrincipal> resultPrincipal; + rv = nsContentUtils::GetSecurityManager()-> + GetChannelResultPrincipal(channel, + getter_AddRefs(resultPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + if (resultPrincipal->Equals(aTriggeringPrincipal)) { + static_cast<mozilla::LoadInfo*>(loadInfo.get())->SetUpgradeInsecureRequests(); + } + } + } + + nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel = do_QueryInterface(channel); if (appCacheChannel) { diff --git a/docshell/base/nsIRefreshURI.idl b/docshell/base/nsIRefreshURI.idl index 5abd829da..04f18eee0 100644 --- a/docshell/base/nsIRefreshURI.idl +++ b/docshell/base/nsIRefreshURI.idl @@ -19,9 +19,8 @@ interface nsIRefreshURI : nsISupports { * * @param aUri The uri to refresh. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aMillis The number of milliseconds to wait. * @param aRepeat Flag to indicate if the uri is to be * repeatedly refreshed every aMillis milliseconds. @@ -37,9 +36,8 @@ interface nsIRefreshURI : nsISupports { * * @param aURI The URI to refresh. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aMillis The number of milliseconds by which this refresh would * be delayed if it were not being forced. * @param aMetaRefresh Flag to indicate if this is a meta refresh. @@ -70,9 +68,8 @@ interface nsIRefreshURI : nsISupports { * * @param aBaseURI base URI to resolve refresh uri with. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aHeader The meta refresh header string. */ void setupRefreshURIFromHeader(in nsIURI aBaseURI, |