diff --git a/packages/browser-rum/src/domain/deflate/deflateWorker.ts b/packages/browser-rum/src/domain/deflate/deflateWorker.ts index 3b9ac21c1b..d8eac03b1f 100644 --- a/packages/browser-rum/src/domain/deflate/deflateWorker.ts +++ b/packages/browser-rum/src/domain/deflate/deflateWorker.ts @@ -43,7 +43,11 @@ type DeflateWorkerState = export type CreateDeflateWorker = typeof createDeflateWorker export function createDeflateWorker(configuration: RumConfiguration): DeflateWorker { - return new Worker(configuration.workerUrl || URL.createObjectURL(new Blob([__BUILD_ENV__WORKER_STRING__]))) + return new Worker( + getWorkerTrustedTypePolicy().createScriptURL( + configuration.workerUrl || URL.createObjectURL(new Blob([__BUILD_ENV__WORKER_STRING__])) + ) + ) } let state: DeflateWorkerState = { status: DeflateWorkerStatus.Nil } @@ -150,3 +154,25 @@ function onError(configuration: RumConfiguration, source: string, error: unknown }) } } + +// Trusted Types are not yet in TypeScript lib +interface WindowWithTrustedTypes { + trustedTypes?: { + createPolicy(name: string, policy: TrustedTypesPolicy): TrustedTypesPolicy + } +} + +interface TrustedTypesPolicy { + createScriptURL(url: string): string +} + +let workerTrustedTypePolicyCache: TrustedTypesPolicy | undefined +function getWorkerTrustedTypePolicy(): TrustedTypesPolicy { + if (!workerTrustedTypePolicyCache) { + const trustedTypes = (window as WindowWithTrustedTypes).trustedTypes + workerTrustedTypePolicyCache = trustedTypes + ? trustedTypes.createPolicy('datadog-worker', { createScriptURL: (url) => url }) + : { createScriptURL: (url) => url } + } + return workerTrustedTypePolicyCache +} diff --git a/test/e2e/lib/framework/serverApps/mock.ts b/test/e2e/lib/framework/serverApps/mock.ts index 148f813600..d5742f3072 100644 --- a/test/e2e/lib/framework/serverApps/mock.ts +++ b/test/e2e/lib/framework/serverApps/mock.ts @@ -197,6 +197,21 @@ export function createMockServerApp(servers: Servers, setup: string, setupOption res.end() }) + app.get('/trusted-types-csp', (_req, res) => { + res.header( + 'Content-Security-Policy', + [ + `connect-src ${servers.datadogHttpApi.origin} ${servers.base.origin} ${servers.crossOrigin.origin} https://quota.browser-intake-datadoghq.com`, + `script-src 'self' 'unsafe-inline' ${servers.crossOrigin.origin}`, + "worker-src blob: 'self'", + "require-trusted-types-for 'script'", + 'trusted-types datadog-chunks datadog-worker', + ].join(';') + ) + res.send(setup) + res.end() + }) + app.get(/datadog-(?[a-z-]*)\.js/, (req, res) => { const { originalUrl, params } = req diff --git a/test/e2e/scenario/transport.scenario.ts b/test/e2e/scenario/transport.scenario.ts index afcde9d35f..1fa00fc6a5 100644 --- a/test/e2e/scenario/transport.scenario.ts +++ b/test/e2e/scenario/transport.scenario.ts @@ -100,5 +100,39 @@ test.describe('transport', () => { expect(cspDocLog, "'CSP doc' log").toBeTruthy() }) }) + + createTest('workerUrl initialization parameter') + .withRum({ compressIntakeRequests: true, workerUrl: '/worker.js' }) + .withBasePath('/no-blob-worker-csp') + .run(async ({ intakeRegistry, flushEvents }) => { + await flushEvents() + expect(intakeRegistry.rumRequests.length).toBeGreaterThan(0) + }) + + test.describe('Trusted Types CSP', () => { + createTest('supports Trusted Types CSP with compression worker') + .withRum({ compressIntakeRequests: true }) + .withBasePath('/trusted-types-csp') + .run(async ({ flushEvents, intakeRegistry }) => { + await flushEvents() + expect(intakeRegistry.rumRequests.length).toBeGreaterThan(0) + }) + + createTest('supports Trusted Types CSP with workerUrl') + .withRum({ compressIntakeRequests: true, workerUrl: '/worker.js' }) + .withBasePath('/trusted-types-csp') + .run(async ({ intakeRegistry, flushEvents }) => { + await flushEvents() + expect(intakeRegistry.rumRequests.length).toBeGreaterThan(0) + }) + + createTest('supports Trusted Types CSP with session replay chunk') + .withRum({ sessionReplaySampleRate: 100 }) + .withBasePath('/trusted-types-csp') + .run(async ({ flushEvents, intakeRegistry }) => { + await flushEvents() + expect(intakeRegistry.rumRequests.length).toBeGreaterThan(0) + }) + }) }) }) diff --git a/webpack.base.ts b/webpack.base.ts index 611fafc352..0fe3d9a59d 100644 --- a/webpack.base.ts +++ b/webpack.base.ts @@ -32,6 +32,9 @@ export default ({ path: path.resolve('./bundle'), chunkFormat: 'module', chunkLoading: 'import', + trustedTypes: { + policyName: 'datadog-chunks', + }, }, target: ['web', 'es2020'], devtool: false,