summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fenced-frame/disallowed-navigations.https.html
blob: 54fa95f16f469c59101e4f0c43206824770bcffe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
<title>Fenced frame disallowed navigations</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="resources/utils.js"></script>
<script src="/fetch/private-network-access/resources/support.sub.js"></script>

<body>

<script>
// Baseline tests:
//   - Embedder can navigate iframe to blob: URL
//   - Embedder can navigate iframe to data: URL
//   - Same-origin embedder can navigate iframe to javascript: URL
//   - Embedder can navigate iframe to http: URL
// Fenced frame tests:
//   - Embedder cannot navigate fenced frame to blob: URL
//   - Embedder cannot navigate fenced frame to data: URL
//   - Same-origin embedder cannot navigate fenced frame to
//     javascript: URL
//   - Embedder cannot navigate fenced frame to http: URL

// Fenced frames are always put in the public IP address space which is the
// least privileged. In case a navigation to a local data: URL or blob: URL
// resource is allowed, they would only be able to fetch things that are *also*
// in the public IP address space. So for the document described by these local
// URLs, we'll set them up to only communicate back to the outer page via
// resources obtained in the public address space.
const kPublicUtils = resolveUrl("resources/utils.js", Server.HTTPS_PUBLIC);

// These are just baseline tests asserting that this test's machinery to load
// blob:, data:, and javascript: URLs work properly in contexts where they are
// expected to.
promise_test(async () => {
  const key = token();
  attachIFrame(`data:text/html, ${createLocalSource(key, kPublicUtils)}`);
  const result = await nextValueFromServer(key);
  assert_equals(result, "LOADED");
}, "iframe data: URL");

promise_test(async () => {
  const key = token();
  const blobURL = URL.createObjectURL(
      new Blob([`${createLocalSource(key, kPublicUtils)}`],
               {type: 'text/html'}));
  attachIFrame(blobURL);
  const result = await nextValueFromServer(key);
  assert_equals(result, "LOADED");
}, "iframe blob: URL");

promise_test(async () => {
  const iframe = attachIFrameContext();
  iframe.src = "javascript:window.jsURLExecuted = true;"
  await iframe.execute(async () => {
    assert_equals(window.jsURLExecuted, true);
  });
}, "iframe javascript: URL");

// The following tests ensure that an embedder cannot navigate a fenced frame
// to:
//   - data: URLs
//   - blob: URLs
//   - javascript: URLs
//   - http: URLs
function getTimeoutPromise(t) {
  return new Promise(resolve =>
      t.step_timeout(() => resolve("NOT LOADED"), 2000));
}

promise_test(async t => {
  const key = token();
  attachFencedFrame(`data:text/html, ${createLocalSource(key, kPublicUtils)}`);
  const loaded_promise = nextValueFromServer(key);
  const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
  assert_equals(result, "NOT LOADED");
}, `fenced frame data: URL`);

promise_test(async t => {
  const key = token();
  const blobURL = URL.createObjectURL(
      new Blob([`${createLocalSource(key, kPublicUtils)}`],
               {type: 'text/html'}));
  attachFencedFrame(blobURL);
  const loaded_promise = nextValueFromServer(key);
  const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
  assert_equals(result, "NOT LOADED");
}, `fenced frame blob: URL`);

promise_test(async t => {
  const fencedframe = attachFencedFrameContext();
  fencedframe.src = "javascript:window.jsURLExecuted = true;"
  // Just in case the javascript URL executes asynchronously, let's wait for
  // it.
  await getTimeoutPromise(t);
  await fencedframe.execute(async () => {
    assert_equals(window.jsURLExecuted, undefined);
  });
}, `fenced frame javascript: URL`);

promise_test(async t => {
  const key = token();
  let http_url = new URL("resources/embeddee.html",
      get_host_info().HTTP_ORIGIN + location.pathname);
  http_url = generateURL(http_url, [key]);
  assert_equals(http_url.protocol, "http:");
  const fencedframe = attachFencedFrame(http_url);
  const loaded_promise = nextValueFromServer(key);
  const result = await Promise.any([loaded_promise, getTimeoutPromise(t)]);
  assert_equals(result, "NOT LOADED");
}, `fenced frame http: URL`);

</script>

</body>