diff --git a/dom/base/nsContentPolicyUtils.h b/dom/base/nsContentPolicyUtils.h index 616e439fee95..bbb5c4c8ba6b 100644 --- a/dom/base/nsContentPolicyUtils.h +++ b/dom/base/nsContentPolicyUtils.h @@ -114,6 +114,7 @@ NS_CP_ContentTypeName(uint32_t contentType) CASE_RETURN( TYPE_FETCH ); CASE_RETURN( TYPE_IMAGESET ); CASE_RETURN( TYPE_WEB_MANIFEST ); + CASE_RETURN( TYPE_SAVEAS_DOWNLOAD ); CASE_RETURN( TYPE_INTERNAL_SCRIPT ); CASE_RETURN( TYPE_INTERNAL_WORKER ); CASE_RETURN( TYPE_INTERNAL_SHARED_WORKER ); diff --git a/dom/base/nsIContentPolicy.idl b/dom/base/nsIContentPolicy.idl index 3b0fe18a46a8..19a84ef89fdf 100644 --- a/dom/base/nsIContentPolicy.idl +++ b/dom/base/nsIContentPolicy.idl @@ -181,6 +181,11 @@ interface nsIContentPolicy : nsISupports */ const nsContentPolicyType TYPE_WEB_MANIFEST = 22; + /** + * Indicates an save-as link download from the front-end code. + */ + const nsContentPolicyType TYPE_SAVEAS_DOWNLOAD = 43; + /** * Indicates an internal constant for scripts loaded through script * elements. diff --git a/dom/cache/DBSchema.cpp b/dom/cache/DBSchema.cpp index 38634b88aaa3..40ce654b7086 100644 --- a/dom/cache/DBSchema.cpp +++ b/dom/cache/DBSchema.cpp @@ -311,6 +311,7 @@ static_assert(nsIContentPolicy::TYPE_INVALID == 0 && nsIContentPolicy::TYPE_FETCH == 20 && nsIContentPolicy::TYPE_IMAGESET == 21 && nsIContentPolicy::TYPE_WEB_MANIFEST == 22 && + nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD == 43 && nsIContentPolicy::TYPE_INTERNAL_SCRIPT == 23 && nsIContentPolicy::TYPE_INTERNAL_WORKER == 24 && nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER == 25 && diff --git a/dom/fetch/InternalRequest.cpp b/dom/fetch/InternalRequest.cpp index 9fe13d36e50a..11eea7919aad 100644 --- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -324,6 +324,9 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte case nsIContentPolicy::TYPE_WEB_MANIFEST: context = RequestContext::Manifest; break; + case nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD: + context = RequestContext::Internal; + break; default: MOZ_ASSERT(false, "Unhandled nsContentPolicyType value"); break; diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index b09dd18f8a88..911efeb49173 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -53,7 +53,7 @@ namespace dom { * image | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD, TYPE_INTERNAL_IMAGE_FAVICON * imageset | TYPE_IMAGESET * import | Not supported by Gecko - * internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER + * internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER, TYPE_SAVEAS_DOWNLOAD * location | * manifest | TYPE_WEB_MANIFEST * object | TYPE_INTERNAL_OBJECT diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index b4b96fe9a05c..2322a35bfa60 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -480,6 +480,12 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) break; } + case nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD: { + mimeTypeGuess = EmptyCString(); + requestingContext = aLoadInfo->LoadingNode(); + break; + } + default: // nsIContentPolicy::TYPE_INVALID MOZ_ASSERT(false, "can not perform security check without a valid contentType"); diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp index 13830424232c..ccc89e724ea5 100644 --- a/dom/security/nsMixedContentBlocker.cpp +++ b/dom/security/nsMixedContentBlocker.cpp @@ -576,6 +576,13 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect, *aDecision = ACCEPT; return NS_OK; + // Creating insecure connections for a save-as link download is acceptable. + // This download is completely disconnected from the docShell, but still + // using the same loading principal. + case TYPE_SAVEAS_DOWNLOAD: + *aDecision = ACCEPT; + return NS_OK; + // Static display content is considered moderate risk for mixed content so // these will be blocked according to the mixed display preference case TYPE_IMAGE: