mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 08:48:39 +09:00
Issue #2402 - Workers.setTimeout/setInterval must handle CSP rejections. https://bugzilla.mozilla.org/show_bug.cgi?id=1490165 Has some namespace issues adding the files, so differs slightly.
This commit is contained in:
parent
0e0ec8cb20
commit
e74612e23e
10 changed files with 270 additions and 65 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/Function.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/CSPEvalChecker.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/ModuleScript.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
|
@ -52,7 +53,8 @@ public:
|
|||
Function& aFunction,
|
||||
nsTArray<JS::Heap<JS::Value>>&& aArguments);
|
||||
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aExpression);
|
||||
const nsAString& aExpression, bool* aAllowEval,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual const nsAString& GetHandlerText() override;
|
||||
|
||||
|
|
@ -182,54 +184,6 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSScriptTimeoutHandler)
|
||||
|
||||
static bool
|
||||
CheckCSPForEval(JSContext* aCx, nsGlobalWindow* aWindow, ErrorResult& aError)
|
||||
{
|
||||
// if CSP is enabled, and setTimeout/setInterval was called with a string,
|
||||
// disable the registration and log an error
|
||||
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
||||
if (!doc) {
|
||||
// if there's no document, we don't have to do anything.
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
aError = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
if (aError.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!csp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowsEval = true;
|
||||
bool reportViolation = false;
|
||||
aError = csp->GetAllowsEval(&reportViolation, &allowsEval);
|
||||
if (aError.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
// TODO : need actual script sample in violation report.
|
||||
NS_NAMED_LITERAL_STRING(scriptSample,
|
||||
"call to eval() or related function blocked by CSP");
|
||||
|
||||
// Get the calling location.
|
||||
uint32_t lineNum = 0;
|
||||
nsAutoString fileNameString;
|
||||
if (!nsJSUtils::GetCallingLocation(aCx, fileNameString, &lineNum)) {
|
||||
fileNameString.AssignLiteral("unknown");
|
||||
}
|
||||
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
fileNameString, scriptSample, lineNum,
|
||||
EmptyString(), EmptyString());
|
||||
}
|
||||
|
||||
return allowsEval;
|
||||
}
|
||||
|
||||
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler()
|
||||
: mLineNo(0)
|
||||
, mColumn(0)
|
||||
|
|
@ -273,8 +227,9 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
|
||||
*aAllowEval = CheckCSPForEval(aCx, aWindow, aError);
|
||||
if (aError.Failed() || !*aAllowEval) {
|
||||
aError = CSPEvalChecker::CheckForWindow(aCx, aWindow, aExpression,
|
||||
aAllowEval);
|
||||
if (NS_WARN_IF(aError.Failed()) || !*aAllowEval) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +252,9 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
|||
|
||||
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
||||
WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aExpression)
|
||||
const nsAString& aExpression,
|
||||
bool* aAllowEval,
|
||||
ErrorResult& aError)
|
||||
: mLineNo(0)
|
||||
, mColumn(0)
|
||||
, mExpr(aExpression)
|
||||
|
|
@ -305,6 +262,12 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
|||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
aError = CSPEvalChecker::CheckForWorker(aCx, aWorkerPrivate, aExpression,
|
||||
aAllowEval);
|
||||
if (NS_WARN_IF(aError.Failed()) || !*aAllowEval) {
|
||||
return;
|
||||
}
|
||||
|
||||
Init(aCx);
|
||||
}
|
||||
|
||||
|
|
@ -399,9 +362,15 @@ NS_CreateJSTimeoutHandler(JSContext *aCx, WorkerPrivate* aWorkerPrivate,
|
|||
|
||||
already_AddRefed<nsIScriptTimeoutHandler>
|
||||
NS_CreateJSTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
const nsAString& aExpression)
|
||||
const nsAString& aExpression, ErrorResult& aRv)
|
||||
{
|
||||
bool allowEval = false;
|
||||
RefPtr<nsJSScriptTimeoutHandler> handler =
|
||||
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aExpression);
|
||||
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aExpression, &allowEval,
|
||||
aRv);
|
||||
if (aRv.Failed() || !allowEval) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handler.forget();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue