diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index cd9f03b41427..70c80b17cef4 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -860,6 +860,15 @@ pref("media.webspeech.synth.enabled", true); pref("dom.mozDownloads.enabled", true); pref("dom.downloads.max_retention_days", 7); +// External Helper Application Handling +// +// All external helper application handling can require the docshell to be +// active before allowing the external helper app service to handle content. +// +// To prevent SD card DoS attacks via downloads we disable background handling. +// +pref("security.exthelperapp.disable_background_handling", true); + // Inactivity time in milliseconds after which we shut down the OS.File worker. pref("osfile.reset_worker_delay", 5000); diff --git a/uriloader/base/nsURILoader.cpp b/uriloader/base/nsURILoader.cpp index ece2607e5c93..e1545f272d51 100644 --- a/uriloader/base/nsURILoader.cpp +++ b/uriloader/base/nsURILoader.cpp @@ -49,6 +49,7 @@ #include "nsDocLoader.h" #include "mozilla/Attributes.h" +#include "mozilla/Preferences.h" #ifdef PR_LOGGING PRLogModuleInfo* nsURILoader::mLog = nullptr; @@ -58,6 +59,9 @@ PRLogModuleInfo* nsURILoader::mLog = nullptr; #define LOG_ERROR(args) PR_LOG(nsURILoader::mLog, PR_LOG_ERROR, args) #define LOG_ENABLED() PR_LOG_TEST(nsURILoader::mLog, PR_LOG_DEBUG) +#define NS_PREF_DISABLE_BACKGROUND_HANDLING \ + "security.exthelperapp.disable_background_handling" + /** * The nsDocumentOpenInfo contains the state required when a single * document is being opened in order to discover the content type... @@ -519,6 +523,35 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports * // All attempts to dispatch this content have failed. Just pass it off to // the helper app service. // + + // + // Optionally, we may want to disable background handling by the external + // helper application service. + // + if (mozilla::Preferences::GetBool(NS_PREF_DISABLE_BACKGROUND_HANDLING, + false)) { + // First, we will ensure that the parent docshell is in an active + // state as we will disallow all external application handling unless it is + // in the foreground. + nsCOMPtr docShell(do_GetInterface(m_originalContext)); + if (!docShell) { + // If we can't perform our security check we definitely don't want to go + // any further! + LOG(("Failed to get DocShell to ensure it is active before anding off to " + "helper app service. Aborting.")); + return NS_ERROR_FAILURE; + } + + // Ensure the DocShell is active before continuing. + bool isActive = false; + docShell->GetIsActive(&isActive); + if (!isActive) { + LOG((" Check for active DocShell returned false. Aborting hand off to " + "helper app service.")); + return NS_ERROR_DOM_SECURITY_ERR; + } + } + nsCOMPtr helperAppService = do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv); if (helperAppService) {