Skip to content

Commit

Permalink
Bug 1931295 - Implement Trusted Types support for Worker/SharedWorker…
Browse files Browse the repository at this point in the history
…'s constructors for Window. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D229344
  • Loading branch information
fred-wang committed Nov 29, 2024
1 parent 08bd156 commit a05e005
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 30 deletions.
18 changes: 16 additions & 2 deletions dom/security/trusted-types/TrustedTypeUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
TrustedScriptOrNullIsEmptyString>) {
return aInput.IsNullIsEmptyString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return aInput.IsUSVString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
Unused << aInput;
return true;
Expand All @@ -262,6 +266,10 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
TrustedScriptOrNullIsEmptyString>) {
return &aInput.GetAsNullIsEmptyString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return &aInput.GetAsUSVString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
return aInput;
}
Expand All @@ -283,7 +291,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
return aInput.IsTrustedScript();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrString>) {
TrustedScriptURLOrString> ||
std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return aInput.IsTrustedScriptURL();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
Expand All @@ -308,7 +318,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
return &aInput.GetAsTrustedScript().mData;
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrString>) {
TrustedScriptURLOrString> ||
std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return &aInput.GetAsTrustedScriptURL().mData;
}
Unused << aInput;
Expand Down Expand Up @@ -433,6 +445,8 @@ IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(FunctionOrTrustedScriptOrString,
TrustedScript, nsIGlobalObject);
IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptURLOrString,
TrustedScriptURL, const nsINode);
IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptURLOrUSVString,
TrustedScriptURL, nsIGlobalObject);

MOZ_CAN_RUN_SCRIPT const nsAString*
GetTrustedTypesCompliantStringForTrustedHTML(const nsAString& aInput,
Expand Down
5 changes: 5 additions & 0 deletions dom/security/trusted-types/TrustedTypeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class TrustedScriptOrNullIsEmptyString;
class FunctionOrTrustedScriptOrString;
class TrustedScriptURL;
class TrustedScriptURLOrString;
class TrustedScriptURLOrUSVString;
class TrustedHTMLOrTrustedScriptOrTrustedScriptURLOrString;

namespace TrustedTypeUtils {
Expand Down Expand Up @@ -92,6 +93,10 @@ MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantString(
const TrustedScriptURLOrString& aInput, const nsAString& aSink,
const nsAString& aSinkGroup, const nsINode& aNode,
Maybe<nsAutoString>& aResultHolder, ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantString(
const TrustedScriptURLOrUSVString& aInput, const nsAString& aSink,
const nsAString& aSinkGroup, nsIGlobalObject& aGlobalObject,
Maybe<nsAutoString>& aResultHolder, ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT const nsAString*
GetTrustedTypesCompliantStringForTrustedHTML(const nsAString& aInput,
const nsAString& aSink,
Expand Down
2 changes: 1 addition & 1 deletion dom/webidl/SharedWorker.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[Exposed=Window]
interface SharedWorker : EventTarget {
[Throws]
constructor(USVString scriptURL,
constructor((TrustedScriptURL or USVString) scriptURL,
optional (DOMString or WorkerOptions) options = {});

readonly attribute MessagePort port;
Expand Down
2 changes: 1 addition & 1 deletion dom/webidl/Worker.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface Worker : EventTarget {
[Throws]
constructor(USVString scriptURL, optional WorkerOptions options = {});
constructor((TrustedScriptURL or USVString) scriptURL, optional WorkerOptions options = {});

undefined terminate();

Expand Down
21 changes: 16 additions & 5 deletions dom/workers/Worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "nsDebug.h"
#include "mozilla/dom/WorkerStatus.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/TrustedTypeUtils.h"
#include "mozilla/dom/TrustedTypesConstants.h"

#ifdef XP_WIN
# undef PostMessage
Expand All @@ -29,10 +31,9 @@
namespace mozilla::dom {

/* static */
already_AddRefed<Worker> Worker::Constructor(const GlobalObject& aGlobal,
const nsAString& aScriptURL,
const WorkerOptions& aOptions,
ErrorResult& aRv) {
already_AddRefed<Worker> Worker::Constructor(
const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv) {
JSContext* cx = aGlobal.Context();

nsCOMPtr<nsIGlobalObject> globalObject =
Expand All @@ -45,8 +46,18 @@ already_AddRefed<Worker> Worker::Constructor(const GlobalObject& aGlobal,
return nullptr;
}

constexpr nsLiteralString sink = u"Worker constructor"_ns;
Maybe<nsAutoString> compliantStringHolder;
const nsAString* compliantString =
TrustedTypeUtils::GetTrustedTypesCompliantString(
aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject,
compliantStringHolder, aRv);
if (aRv.Failed()) {
return nullptr;
}

RefPtr<WorkerPrivate> workerPrivate = WorkerPrivate::Constructor(
cx, aScriptURL, false /* aIsChromeWorker */, WorkerKindDedicated,
cx, *compliantString, false /* aIsChromeWorker */, WorkerKindDedicated,
aOptions.mCredentials, aOptions.mType, aOptions.mName, VoidCString(),
nullptr /*aLoadInfo */, aRv);
if (NS_WARN_IF(aRv.Failed())) {
Expand Down
11 changes: 7 additions & 4 deletions dom/workers/Worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@ struct StructuredSerializeOptions;
struct WorkerOptions;
class WorkerPrivate;

class TrustedScriptURLOrUSVString;

class Worker : public DOMEventTargetHelper, public SupportsWeakPtr {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Worker,
DOMEventTargetHelper)
static already_AddRefed<Worker> Constructor(const GlobalObject& aGlobal,
const nsAString& aScriptURL,
const WorkerOptions& aOptions,
ErrorResult& aRv);
// TODO(bug 1749042): Mark as MOZ_CAN_RUN_SCRIPT when IDL constructors can be.
MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed<Worker> Constructor(
const GlobalObject& aGlobal,
const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv);

JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
Expand Down
27 changes: 20 additions & 7 deletions dom/workers/sharedworkers/SharedWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "mozilla/dom/RemoteWorkerTypes.h"
#include "mozilla/dom/SharedWorkerBinding.h"
#include "mozilla/dom/SharedWorkerChild.h"
#include "mozilla/dom/TrustedTypeUtils.h"
#include "mozilla/dom/TrustedTypesConstants.h"
#include "mozilla/dom/WorkerBinding.h"
#include "mozilla/dom/WorkerLoadInfo.h"
#include "mozilla/dom/WorkerPrivate.h"
Expand Down Expand Up @@ -58,7 +60,7 @@ SharedWorker::~SharedWorker() {

// static
already_AddRefed<SharedWorker> SharedWorker::Constructor(
const GlobalObject& aGlobal, const nsAString& aScriptURL,
const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL,
const StringOrWorkerOptions& aOptions, ErrorResult& aRv) {
AssertIsOnMainThread();

Expand All @@ -74,7 +76,7 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(

// static
already_AddRefed<SharedWorker> SharedWorker::Constructor(
const GlobalObject& aGlobal, const nsAString& aScriptURL,
const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv) {
AssertIsOnMainThread();

Expand Down Expand Up @@ -130,10 +132,22 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(

JSContext* cx = aGlobal.Context();

constexpr nsLiteralString sink = u"SharedWorker constructor"_ns;
Maybe<nsAutoString> compliantStringHolder;
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
const nsAString* compliantString =
TrustedTypeUtils::GetTrustedTypesCompliantString(
aScriptURL, sink, kTrustedTypesOnlySinkGroup, *global,
compliantStringHolder, aRv);
if (aRv.Failed()) {
return nullptr;
}

WorkerLoadInfo loadInfo;
aRv = WorkerPrivate::GetLoadInfo(
cx, window, nullptr, aScriptURL, aOptions.mType, aOptions.mCredentials,
false, WorkerPrivate::OverrideLoadGroup, WorkerKindShared, &loadInfo);
aRv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, *compliantString,
aOptions.mType, aOptions.mCredentials, false,
WorkerPrivate::OverrideLoadGroup,
WorkerKindShared, &loadInfo);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
Expand Down Expand Up @@ -203,7 +217,6 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(

// We don't actually care about this MessageChannel, but we use it to 'steal'
// its 2 connected ports.
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
Expand Down Expand Up @@ -247,7 +260,7 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(
}

RemoteWorkerData remoteWorkerData(
nsString(aScriptURL), baseURL, resolvedScriptURL, aOptions,
nsString(*compliantString), baseURL, resolvedScriptURL, aOptions,
loadingPrincipalInfo, principalInfo, partitionedPrincipalInfo,
loadInfo.mUseRegularPrincipal, loadInfo.mUsingStorageAccess, cjsData,
loadInfo.mDomain, isSecureContext, ipcClientInfo, loadInfo.mReferrerInfo,
Expand Down
12 changes: 8 additions & 4 deletions dom/workers/sharedworkers/SharedWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class StringOrWorkerOptions;
struct WorkerOptions;

class SharedWorkerChild;
class TrustedScriptURLOrUSVString;

/**
* DOM binding. Holds a SharedWorkerChild. Must exist on the main thread because
Expand All @@ -44,8 +45,10 @@ class SharedWorker final : public DOMEventTargetHelper {
bool mFrozen;

public:
static already_AddRefed<SharedWorker> Constructor(
const GlobalObject& aGlobal, const nsAString& aScriptURL,
// TODO(bug 1749042): Mark as MOZ_CAN_RUN_SCRIPT when IDL constructors can be.
MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed<SharedWorker> Constructor(
const GlobalObject& aGlobal,
const TrustedScriptURLOrUSVString& aScriptURL,
const StringOrWorkerOptions& aOptions, ErrorResult& aRv);

MessagePort* Port();
Expand Down Expand Up @@ -81,8 +84,9 @@ class SharedWorker final : public DOMEventTargetHelper {
void Thaw();

private:
static already_AddRefed<SharedWorker> Constructor(
const GlobalObject& aGlobal, const nsAString& aScriptURL,
MOZ_CAN_RUN_SCRIPT static already_AddRefed<SharedWorker> Constructor(
const GlobalObject& aGlobal,
const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv);

SharedWorker(nsPIDOMWindowInner* aWindow, SharedWorkerChild* aActor,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
[worker-constructor.https.html]
expected:
if tsan: CRASH
[Block Worker creation via string]
expected: FAIL

[Block SharedWorker creation via string]
expected: FAIL

[Block ServiceWorker creation via String]
expected: FAIL

Expand Down

0 comments on commit a05e005

Please sign in to comment.