diff --git a/fetch/private-network-access/resources/support.sub.js b/fetch/private-network-access/resources/support.sub.js index 8ffdf100ee8d81f..a104021d158d932 100644 --- a/fetch/private-network-access/resources/support.sub.js +++ b/fetch/private-network-access/resources/support.sub.js @@ -635,6 +635,23 @@ async function workerFetchTest(t, { source, target, expected }) { assert_equals(message, expected.message, "response body"); } +async function workerBlobFetchTest(t, { source, target, expected }) { + const targetUrl = preflightUrl(target); + + const fetcherUrl = resolveUrl( + 'resources/worker-blob-fetcher.html', sourceResolveOptions(source)); + + const reply = futureMessage(); + const iframe = await appendIframe(t, document, fetcherUrl); + + iframe.contentWindow.postMessage({ url: targetUrl.href }, "*"); + + const { error, status, message } = await reply; + assert_equals(error, expected.error, "fetch error"); + assert_equals(status, expected.status, "response status"); + assert_equals(message, expected.message, "response body"); +} + async function sharedWorkerFetchTest(t, { source, target, expected }) { const targetUrl = preflightUrl(target); diff --git a/fetch/private-network-access/resources/worker-blob-fetcher.html b/fetch/private-network-access/resources/worker-blob-fetcher.html new file mode 100644 index 000000000000000..18a454b7fa36288 --- /dev/null +++ b/fetch/private-network-access/resources/worker-blob-fetcher.html @@ -0,0 +1,45 @@ + + +Worker Fetcher + diff --git a/fetch/private-network-access/worker-blob-fetch.window.js b/fetch/private-network-access/worker-blob-fetch.window.js new file mode 100644 index 000000000000000..80374143a283f42 --- /dev/null +++ b/fetch/private-network-access/worker-blob-fetch.window.js @@ -0,0 +1,143 @@ +// META: script=/common/utils.js +// META: script=resources/support.sub.js +// +// Spec: https://wicg.github.io/private-network-access/#integration-fetch +// +// These tests check that fetches from within `Worker` scripts loaded from blob +// URLs are subject to Private Network Access checks, just like fetches from +// within documents. +// +// This file covers only those tests that must execute in a non-secure context. +// Other tests are defined in: worker-fetch.https.window.js + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_LOCAL }, + target: { server: Server.HTTP_LOCAL }, + expected: WorkerFetchTestResult.SUCCESS, +}), "local to local: success."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_PRIVATE }, + target: { + server: Server.HTTP_LOCAL, + behavior: { + preflight: PreflightBehavior.optionalSuccess(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "private to local: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_PRIVATE }, + target: { server: Server.HTTP_PRIVATE }, + expected: WorkerFetchTestResult.SUCCESS, +}), "private to private: success."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_PUBLIC }, + target: { + server: Server.HTTP_LOCAL, + behavior: { + preflight: PreflightBehavior.optionalSuccess(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "public to local: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_PUBLIC }, + target: { + server: Server.HTTP_PRIVATE, + behavior: { + preflight: PreflightBehavior.optionalSuccess(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "public to private: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTP_PUBLIC }, + target: { server: Server.HTTP_PUBLIC }, + expected: WorkerFetchTestResult.SUCCESS, +}), "public to public: success."); + +promise_test(t => workerBlobFetchTest(t, { + source: { + server: Server.HTTP_LOCAL, + treatAsPublic: true, + }, + target: { + server: Server.HTTP_LOCAL, + behavior: { preflight: PreflightBehavior.optionalSuccess(token()) }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "treat-as-public to local: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { + server: Server.HTTP_LOCAL, + treatAsPublic: true, + }, + target: { + server: Server.HTTP_PRIVATE, + behavior: { + preflight: PreflightBehavior.optionalSuccess(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "treat-as-public to private: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { + server: Server.HTTP_LOCAL, + treatAsPublic: true, + }, + target: { + server: Server.HTTP_PUBLIC, + behavior: { response: ResponseBehavior.allowCrossOrigin() }, + }, + expected: WorkerFetchTestResult.SUCCESS, +}), "treat-as-public to public: success."); + +// The following tests verify that workers served over HTTPS are not allowed to +// make private network requests because they are not secure contexts. + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTPS_PRIVATE }, + target: { + server: Server.HTTP_LOCAL, + behavior: { + preflight: PreflightBehavior.success(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "private https to local: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTPS_PUBLIC }, + target: { + server: Server.HTTP_PRIVATE, + behavior: { + preflight: PreflightBehavior.success(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "public https to private: failure."); + +promise_test(t => workerBlobFetchTest(t, { + source: { server: Server.HTTPS_PUBLIC }, + target: { + server: Server.HTTP_LOCAL, + behavior: { + preflight: PreflightBehavior.success(token()), + response: ResponseBehavior.allowCrossOrigin(), + }, + }, + expected: WorkerFetchTestResult.FAILURE, +}), "public https to local: failure.");