mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1478037. Allow bookmarklets to run even on pages with a CSP. r=ckerschb
The removal of the second CSP check is fixing a regression introduced in bug 965637. See https://github.com/whatwg/html/issues/4651#issuecomment-495050351 for details. We may want to re-introduce that check depending on the outcome of that issue, but if so we should do that only if the target document's principal subsumes our triggering principal. This commit will not allow bookmarklets to access subresources that CSP blocks, but will at least allow them to run. Differential Revision: https://phabricator.services.mozilla.com/D33047 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
6e3bc45fd5
commit
63b07e7115
@ -39,7 +39,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsITextToSubURI.h"
|
||||
@ -49,9 +48,9 @@
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/PopupBlocker.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
|
||||
@ -160,8 +159,10 @@ nsresult nsJSThunk::EvaluateScript(
|
||||
nsresult rv;
|
||||
|
||||
// CSP check: javascript: URIs disabled unless "inline" scripts are
|
||||
// allowed.
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCsp();
|
||||
// allowed. Here we use the CSP of the thing that started the load,
|
||||
// which is the CSPToInherit of the loadInfo.
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp =
|
||||
static_cast<mozilla::net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
|
||||
if (csp) {
|
||||
bool allowsInlineScript = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
@ -175,33 +176,26 @@ nsresult nsJSThunk::EvaluateScript(
|
||||
&allowsInlineScript);
|
||||
|
||||
// return early if inline scripts are not allowed
|
||||
if (!allowsInlineScript) {
|
||||
if (NS_FAILED(rv) || !allowsInlineScript) {
|
||||
return NS_ERROR_DOM_RETVAL_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
// for document navigations we need to check the CSP of the previous document.
|
||||
csp = nullptr;
|
||||
mozilla::dom::Document* prevDoc = aOriginalInnerWindow->GetExtantDoc();
|
||||
if (prevDoc) {
|
||||
csp = prevDoc->GetCsp();
|
||||
}
|
||||
if (csp) {
|
||||
bool allowsInlineScript = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
EmptyString(), // aNonce
|
||||
true, // aParserCreated
|
||||
nullptr, // aElement,
|
||||
nullptr, // nsICSPEventListener
|
||||
EmptyString(), // aContent
|
||||
0, // aLineNumber
|
||||
0, // aColumnNumber
|
||||
&allowsInlineScript);
|
||||
// return early if inline scripts are not allowed
|
||||
if (!allowsInlineScript) {
|
||||
return NS_ERROR_DOM_RETVAL_UNDEFINED;
|
||||
}
|
||||
}
|
||||
// Based on the outcome of https://github.com/whatwg/html/issues/4651 we may
|
||||
// want to also test against the CSP of the document we'll be running against
|
||||
// (which is targetDoc below). If we do that, we should make sure to only do
|
||||
// that test if targetDoc->NodePrincipal() subsumes
|
||||
// loadInfo->TriggeringPrincipal(). If it doesn't, then someone
|
||||
// more-privileged (our UI or an extension) started the load and the load
|
||||
// should not be subject to the target document's CSP.
|
||||
//
|
||||
// The "more privileged" assumption is safe, because if the triggering
|
||||
// principal does not subsume targetDoc->NodePrincipal() we won't run the
|
||||
// script at all. More precisely, we test that "principal" subsumes the
|
||||
// target's principal, but "principal" should never be higher-privilege than
|
||||
// the triggering principal here: it's either the triggering principal, or the
|
||||
// principal of the document we started the load against if the triggering
|
||||
// principal is system.
|
||||
|
||||
// Get the global object we should be running on.
|
||||
nsIScriptGlobalObject* global = GetGlobalObject(aChannel);
|
||||
@ -209,16 +203,6 @@ nsresult nsJSThunk::EvaluateScript(
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Sandboxed document check: javascript: URI's are disabled
|
||||
// in a sandboxed document unless 'allow-scripts' was specified.
|
||||
mozilla::dom::Document* doc = aOriginalInnerWindow->GetExtantDoc();
|
||||
if (doc && doc->HasScriptsBlockedBySandbox()) {
|
||||
return NS_ERROR_DOM_RETVAL_UNDEFINED;
|
||||
}
|
||||
|
||||
// Push our popup control state
|
||||
AutoPopupStatePusher popupStatePusher(aPopupState);
|
||||
|
||||
// Make sure we still have the same inner window as we used to.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = do_QueryInterface(global);
|
||||
nsPIDOMWindowInner* innerWin = win->GetCurrentInnerWindow();
|
||||
@ -227,6 +211,17 @@ nsresult nsJSThunk::EvaluateScript(
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mozilla::dom::Document* targetDoc = innerWin->GetExtantDoc();
|
||||
|
||||
// Sandboxed document check: javascript: URI execution is disabled
|
||||
// in a sandboxed document unless 'allow-scripts' was specified.
|
||||
if (targetDoc && targetDoc->HasScriptsBlockedBySandbox()) {
|
||||
return NS_ERROR_DOM_RETVAL_UNDEFINED;
|
||||
}
|
||||
|
||||
// Push our popup control state
|
||||
AutoPopupStatePusher popupStatePusher(aPopupState);
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> innerGlobal = do_QueryInterface(innerWin);
|
||||
|
||||
// So far so good: get the script context from its owner.
|
||||
|
Loading…
Reference in New Issue
Block a user