summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dom/locales/en-US/chrome/security/security.properties2
-rw-r--r--dom/security/nsContentSecurityManager.cpp56
-rw-r--r--dom/security/nsContentSecurityManager.h1
3 files changed, 59 insertions, 0 deletions
diff --git a/dom/locales/en-US/chrome/security/security.properties b/dom/locales/en-US/chrome/security/security.properties
index 8efdb0a6d..2be56fb9d 100644
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -85,3 +85,5 @@ BlockScriptWithWrongMimeType=Script from “%1$S” was blocked because of a dis
# LOCALIZATION NOTE: Do not translate "data: URI".
BlockTopLevelDataURINavigation=Navigation to toplevel data: URI not allowed (Blocked loading of: “%1$S”)
+
+BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blocked loading of: “%1$S”)
diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp
index 570730312..f2cbc8fcf 100644
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -92,6 +92,55 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI(nsIChannel* aChannel)
return false;
}
+/* static */ nsresult
+nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
+{
+ // 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.
+
+ nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+ if (!loadInfo) {
+ return NS_OK;
+ }
+
+ nsContentPolicyType type = loadInfo->GetExternalContentPolicyType();
+ if (type == nsIContentPolicy::TYPE_DOCUMENT) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!uri) {
+ return NS_OK;
+ }
+
+ bool isFtpURI = (NS_SUCCEEDED(uri->SchemeIs("ftp", &isFtpURI)) && isFtpURI);
+ if (!isFtpURI) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIDocument> doc;
+ if (nsINode* node = loadInfo->LoadingNode()) {
+ doc = node->OwnerDoc();
+ }
+
+ nsAutoCString spec;
+ uri->GetSpec(spec);
+ NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(spec));
+ const char16_t* params[] = { specUTF16.get() };
+
+ nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+ NS_LITERAL_CSTRING("FTP_URI_BLOCKED"),
+ doc,
+ nsContentUtils::eSECURITY_PROPERTIES,
+ "BlockSubresourceFTP",
+ params, ArrayLength(params));
+
+ return NS_ERROR_CONTENT_BLOCKED;
+}
+
static nsresult
ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
{
@@ -574,6 +623,10 @@ nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
rv = DoContentSecurityChecks(aChannel, loadInfo);
NS_ENSURE_SUCCESS(rv, rv);
+ // Apply this after CSP checks to allow CSP reporting.
+ rv = CheckFTPSubresourceLoad(aChannel);
+ NS_ENSURE_SUCCESS(rv, rv);
+
// now lets set the initalSecurityFlag for subsequent calls
loadInfo->SetInitialSecurityCheckDone(true);
@@ -591,6 +644,9 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
// Are we enforcing security using LoadInfo?
if (loadInfo && loadInfo->GetEnforceSecurity()) {
nsresult rv = CheckChannel(aNewChannel);
+ if (NS_SUCCEEDED(rv)) {
+ rv = CheckFTPSubresourceLoad(aNewChannel);
+ }
if (NS_FAILED(rv)) {
aOldChannel->Cancel(rv);
return rv;
diff --git a/dom/security/nsContentSecurityManager.h b/dom/security/nsContentSecurityManager.h
index bab847743..750dd8803 100644
--- a/dom/security/nsContentSecurityManager.h
+++ b/dom/security/nsContentSecurityManager.h
@@ -36,6 +36,7 @@ public:
private:
static nsresult CheckChannel(nsIChannel* aChannel);
+ static nsresult CheckFTPSubresourceLoad(nsIChannel* aChannel);
virtual ~nsContentSecurityManager() {}