summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/content-security-policy/reporting/post-redirect-stacktrace.https.html
blob: 9815cdfa19bc4c83d28417e2f6af99f4a077676e (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
<!DOCTYPE html>
<head>
  <title>Check for post-redirect leak from StackTrace.</title>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/common/get-host-info.sub.js"></script>
  <script src="/common/utils.js"></script>
</head>
<body>
<script>

const CROSS_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
const CROSS_SITE = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;

const blank_path = "/common/blank.html"
const redirect = url =>
  `/content-security-policy/reporting/support/redirect-throw-function.sub.py?token=${token()}`;

const script_path = "/content-security-policy/reporting/support/throw-function.js"
const script_ref = "#ref"
const script_attribute = "?secret=1234";

promise_setup(async () => {
  await new Promise(r => window.addEventListener("DOMContentLoaded", r));
});

let loadScript = origin => {
  let script = document.createElement("script");
  script.src = origin +
    redirect(origin + script_path + script_attribute + script_ref);
  let script_loaded = new Promise(r => script.onload = r);
  document.head.appendChild(script);
  return script_loaded;
}

// Note: .stack properties on errors are unspecified, but are present in most
// browsers, most of the time. https://github.com/tc39/proposal-error-stacks
// tracks standardizing them. Tests will pass automatically if the .stack
// property isn't present.
let getStack = async (origin) => {
  await loadScript(origin);
  try {
    throw_function();
  } catch (error) {
    if (error.stack)
      return error.stack.toString();
  }
  return "";
};

promise_test(async test => {
  let data = await getStack(CROSS_ORIGIN);
  assert_false(data.includes(script_ref), "Ref not leaked");
  assert_false(data.includes(script_attribute), "Attribute not leaked");
  assert_false(data.includes(script_path), "Path not leaked");
}, "StackTrace do not leak cross-origin post-redirect URL");

promise_test(async test => {
  let data = await getStack(CROSS_SITE);
  assert_false(data.includes(script_ref), "Ref not leaked");
  assert_false(data.includes(script_attribute), "Attribute not leaked");
  assert_false(data.includes(script_path), "Path not leaked");
}, "StackTrace do not leak cross-site post-redirect URL");

let getCspReport = async (origin) => {
  // A promise to a future CSP violation.
  let violation = new Promise(resolve => {
    const observer = new ReportingObserver(reports => {
      observer.disconnect();
      resolve(JSON.stringify(reports));
    });
    observer.observe();
  });

  // This will be blocked by CSP:
  let script = document.createElement("script");
  script.src = origin +
    redirect(origin + script_path + script_attribute + script_ref);
  script.onload = () => { load_image(); };
  document.head.appendChild(script);

  return await violation;
};

// This block is needed to reproduce https://crbug.com/1074316. Without, the
// next test passes. There is no 'source-file' found in report.
// TODO(arthursonzogni): Investigate more. Find why this has side effects.
promise_setup(async test => {
  await getCspReport(CROSS_ORIGIN);
}, "prewarm the cache");

promise_test(async test => {
  let data = await getCspReport(CROSS_ORIGIN);
  assert_false(data.includes(script_ref), "Ref not leaked");
  assert_false(data.includes(script_attribute), "Attribute not leaked");
  assert_false(data.includes(script_path), "Path not leaked");
}, "CSP report do not leak cross-origin post-redirect URL");

promise_test(async test => {
  let data = await getCspReport(CROSS_SITE);
  assert_false(data.includes(script_ref), "Ref not leaked");
  assert_false(data.includes(script_attribute), "Attribute not leaked");
  assert_false(data.includes(script_path), "Path not leaked");
}, "CSP report do not leak cross-site post-redirect URL");

</script>
</body>