Bug 515460 - enforce CSP during frame redirects, r=jst, a=dholbert_sheriff
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -215,16 +215,18 @@ static NS_DEFINE_CID(kDOMScriptObjectFac
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#if defined(DEBUG_bryner) || defined(DEBUG_chb)
//#define DEBUG_DOCSHELL_FOCUS
#define DEBUG_PAGE_CACHE
#endif
#include "nsContentErrors.h"
+#include "nsIChannelPolicy.h"
+#include "nsIContentSecurityPolicy.h"
// Number of documents currently loading
static PRInt32 gNumberOfDocumentsLoading = 0;
// Global count of existing docshells.
static PRInt32 gDocShellCount = 0;
// Global reference to the URI fixup service.
@@ -8275,25 +8277,47 @@ nsDocShell::DoURILoad(nsIURI * aURI,
loadFlags |= nsIChannel::LOAD_INITIAL_DOCUMENT_URI;
}
if (mLoadType == LOAD_ERROR_PAGE) {
// Error pages are LOAD_BACKGROUND
loadFlags |= nsIChannel::LOAD_BACKGROUND;
}
+ // check for Content Security Policy to pass along with the
+ // new channel we are creating
+ nsCOMPtr<nsIChannelPolicy> channelPolicy;
+ if (IsFrame()) {
+ // check the parent docshell for a CSP
+ nsCOMPtr<nsIContentSecurityPolicy> csp;
+ nsCOMPtr<nsIDocShellTreeItem> parentItem;
+ GetSameTypeParent(getter_AddRefs(parentItem));
+ nsCOMPtr<nsIDOMDocument> domDoc(do_GetInterface(parentItem));
+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+ if (doc) {
+ rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (csp) {
+ channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
+ channelPolicy->SetContentSecurityPolicy(csp);
+ channelPolicy->SetLoadType(nsIContentPolicy::TYPE_SUBDOCUMENT);
+ }
+ }
+ }
+
// open a channel for the url
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel),
aURI,
nsnull,
nsnull,
static_cast<nsIInterfaceRequestor *>(this),
- loadFlags);
+ loadFlags,
+ channelPolicy);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
// This is a uri with a protocol scheme we don't know how
// to handle. Embedders might still be interested in
// handling the load, though, so we fire a notification
// before throwing the load away.
PRBool abort = PR_FALSE;
nsresult rv2 = mContentListener->OnStartURIOpen(aURI, &abort);