Bug 1560699 - Download FTP resources instead of rendering them. r=michal
authorJan Andre Ikenmeyer <jan@ikenmeyer.eu>
Sun, 11 Aug 2019 20:46:06 +0000
changeset 487752 29e52be56feee2b08338e7ef65f2fb7347a7f6d5
parent 487751 75a8f67b92b9c1478bb134a6791736d8da87f85d
child 487753 6a5b28ffb92ebbf142e99b372560fb2fa165580b
push id36430
push userdvarga@mozilla.com
push dateWed, 14 Aug 2019 04:09:17 +0000
treeherdermozilla-central@d3deef805f92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1560699
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1560699 - Download FTP resources instead of rendering them. r=michal Differential Revision: https://phabricator.services.mozilla.com/D39702
dom/security/nsContentSecurityManager.cpp
modules/libpref/init/all.js
netwerk/base/nsBaseChannel.cpp
netwerk/base/nsIOService.cpp
netwerk/base/nsIOService.h
netwerk/protocol/ftp/nsFTPChannel.cpp
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -509,22 +509,19 @@ void nsContentSecurityManager::AssertEva
 
   // In the future, we will change this function to return false and abort JS
   // execution without crashing the process. For now, just collect data.
 }
 
 /* static */
 nsresult nsContentSecurityManager::CheckFTPSubresourceLoad(
     nsIChannel* aChannel) {
-  // We dissallow using FTP resources as a subresource almost everywhere.
+  // We dissallow using FTP resources as a subresource everywhere.
   // The only valid way to use FTP resources is loading it as
   // a top level document.
-  if (!mozilla::net::nsIOService::BlockFTPSubresources()) {
-    return NS_OK;
-  }
 
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
   nsContentPolicyType type = loadInfo->GetExternalContentPolicyType();
 
   // Allow top-level FTP documents and save-as download of FTP files on
   // HTTP pages.
   if (type == nsIContentPolicy::TYPE_DOCUMENT ||
       type == nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
@@ -545,23 +542,16 @@ nsresult nsContentSecurityManager::Check
     return NS_OK;
   }
 
   bool isFtpURI = uri->SchemeIs("ftp");
   if (!isFtpURI) {
     return NS_OK;
   }
 
-  // Allow loading FTP subresources in FTP documents, like XML.
-  nsCOMPtr<nsIURI> triggeringURI;
-  triggeringPrincipal->GetURI(getter_AddRefs(triggeringURI));
-  if (triggeringURI && nsContentUtils::SchemeIs(triggeringURI, "ftp")) {
-    return NS_OK;
-  }
-
   nsCOMPtr<Document> doc;
   if (nsINode* node = loadInfo->LoadingNode()) {
     doc = node->OwnerDoc();
   }
 
   nsAutoCString spec;
   uri->GetSpec(spec);
   AutoTArray<nsString, 1> params;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5526,19 +5526,16 @@ pref("media.block-autoplay-until-in-fore
 // behavior of Firefox.
 pref("security.data_uri.unique_opaque_origin", true);
 
 // If true, all toplevel data: URI navigations will be blocked.
 // Please note that manually entering a data: URI in the
 // URL-Bar will not be blocked when flipping this pref.
 pref("security.data_uri.block_toplevel_data_uri_navigations", true);
 
-// If true, all FTP subresource loads will be blocked.
-pref("security.block_ftp_subresources", true);
-
 pref("dom.storageManager.prompt.testing", false);
 pref("dom.storageManager.prompt.testing.allow", false);
 
 
 pref("browser.storageManager.pressureNotification.minIntervalMS", 1200000);
 pref("browser.storageManager.pressureNotification.usageThresholdGB", 5);
 
 pref("browser.sanitizer.loglevel", "Warn");
--- a/netwerk/base/nsBaseChannel.cpp
+++ b/netwerk/base/nsBaseChannel.cpp
@@ -771,17 +771,20 @@ static void CallUnknownTypeSniffer(void*
   nsresult rv = sniffer->GetMIMETypeFromContent(chan, aData, aCount, detected);
   if (NS_SUCCEEDED(rv)) chan->SetContentType(detected);
 }
 
 NS_IMETHODIMP
 nsBaseChannel::OnStartRequest(nsIRequest* request) {
   MOZ_ASSERT_IF(mRequest, request == mRequest);
 
-  if (mPump) {
+  nsAutoCString scheme;
+  mURI->GetScheme(scheme);
+
+  if (mPump && !scheme.EqualsLiteral("ftp")) {
     // If our content type is unknown, use the content type
     // sniffer. If the sniffer is not available for some reason, then we just
     // keep going as-is.
     if (NS_SUCCEEDED(mStatus) &&
         mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE)) {
       mPump->PeekStream(CallUnknownTypeSniffer, static_cast<nsIChannel*>(this));
     }
 
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -181,17 +181,16 @@ static const char kProfileChangeNetResto
 static const char kProfileDoChange[] = "profile-do-change";
 
 // Necko buffer defaults
 uint32_t nsIOService::gDefaultSegmentSize = 4096;
 uint32_t nsIOService::gDefaultSegmentCount = 24;
 
 bool nsIOService::sIsDataURIUniqueOpaqueOrigin = false;
 bool nsIOService::sBlockToplevelDataUriNavigations = false;
-bool nsIOService::sBlockFTPSubresources = false;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 nsIOService::nsIOService()
     : mOffline(true),
       mOfflineForProfileChange(false),
       mManageLinkStatus(false),
       mConnectivity(true),
@@ -262,18 +261,16 @@ nsresult nsIOService::Init() {
   } else
     NS_WARNING("failed to get observer service");
 
   Preferences::AddBoolVarCache(&sIsDataURIUniqueOpaqueOrigin,
                                "security.data_uri.unique_opaque_origin", false);
   Preferences::AddBoolVarCache(
       &sBlockToplevelDataUriNavigations,
       "security.data_uri.block_toplevel_data_uri_navigations", false);
-  Preferences::AddBoolVarCache(&sBlockFTPSubresources,
-                               "security.block_ftp_subresources", true);
   Preferences::AddBoolVarCache(&mOfflineMirrorsConnectivity,
                                OFFLINE_MIRRORS_CONNECTIVITY, true);
 
   gIOService = this;
 
   InitializeNetworkLinkService();
   InitializeProtocolProxyService();
 
@@ -1813,16 +1810,13 @@ bool nsIOService::IsDataURIUniqueOpaqueO
   return sIsDataURIUniqueOpaqueOrigin;
 }
 
 /*static*/
 bool nsIOService::BlockToplevelDataUriNavigations() {
   return sBlockToplevelDataUriNavigations;
 }
 
-/*static*/
-bool nsIOService::BlockFTPSubresources() { return sBlockFTPSubresources; }
-
 NS_IMETHODIMP
 nsIOService::NotImplemented() { return NS_ERROR_NOT_IMPLEMENTED; }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -97,18 +97,16 @@ class nsIOService final : public nsIIOSe
   // reset mHttpHandlerAlreadyShutingDown.
   void SetHttpHandlerAlreadyShutingDown();
 
   bool IsLinkUp();
 
   static bool IsDataURIUniqueOpaqueOrigin();
   static bool BlockToplevelDataUriNavigations();
 
-  static bool BlockFTPSubresources();
-
   // Used to count the total number of HTTP requests made
   void IncrementRequestNumber() { mTotalRequests++; }
   uint32_t GetTotalRequestNumber() { return mTotalRequests; }
   // Used to keep "race cache with network" stats
   void IncrementCacheWonRequestNumber() { mCacheWon++; }
   uint32_t GetCacheWonRequestNumber() { return mCacheWon; }
   void IncrementNetWonRequestNumber() { mNetWon++; }
   uint32_t GetNetWonRequestNumber() { return mNetWon; }
@@ -218,18 +216,16 @@ class nsIOService final : public nsIIOSe
 
   nsTArray<int32_t> mRestrictedPortList;
 
   bool mNetworkNotifyChanged;
 
   static bool sIsDataURIUniqueOpaqueOrigin;
   static bool sBlockToplevelDataUriNavigations;
 
-  static bool sBlockFTPSubresources;
-
   uint32_t mTotalRequests;
   uint32_t mCacheWon;
   uint32_t mNetWon;
 
   // These timestamps are needed for collecting telemetry on PR_Connect,
   // PR_ConnectContinue and PR_Close blocking time.  If we spend very long
   // time in any of these functions we want to know if and what network
   // change has happened shortly before.
--- a/netwerk/protocol/ftp/nsFTPChannel.cpp
+++ b/netwerk/protocol/ftp/nsFTPChannel.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=4 sts=2 sw=2 et cin: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsFTPChannel.h"
 #include "nsFtpConnectionThread.h"  // defines nsFtpState
+#include "nsMimeTypes.h"
 
 #include "nsThreadUtils.h"
 #include "mozilla/Attributes.h"
 
 using namespace mozilla;
 using namespace mozilla::net;
 extern LazyLogModule gFTPLog;
 
@@ -81,16 +82,17 @@ nsFtpChannel::GetProxyInfo(nsIProxyInfo*
 }
 
 //-----------------------------------------------------------------------------
 
 nsresult nsFtpChannel::OpenContentStream(bool async, nsIInputStream** result,
                                          nsIChannel** channel) {
   if (!async) return NS_ERROR_NOT_IMPLEMENTED;
 
+  SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
   RefPtr<nsFtpState> state = new nsFtpState();
 
   nsresult rv = state->Init(this);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   state.forget(result);