summaryrefslogtreecommitdiffstats
path: root/dom/security/test/csp/test_referrerdirective.html
blob: f590460a0f71edf5d8a38bf77a75be5c0a90d5b4 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<!--
  Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=965727
-->
<head>
  <meta charset="utf-8">
  <title>Test for Content Security Policy referrer Directive (Bug 965727)</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<div id="content" style="display: none">

</div>
<pre id="test">
<script class="testbody" type="application/javascript">
/*
 * This tests various referrer policies and the referrer-sending behavior when
 * requesting scripts in different ways:
 *  - cross-origin (https://example.com -> https://test2.example.com)
 *  - same-origin (https://example.com -> https://example.com)
 *  - downgrade (https://example.com -> http://example.com)
 *
 * Each test creates an iframe that loads scripts for each of the checks.  If
 * the scripts are blocked, the test fails (they should run).  When loaded,
 * each script updates a results object in the test page, and then when the
 * test page has finished loading all the scripts, it postMessages back to this
 * page.  Once all tests are done, the results are checked.
 */

var testData = {
  'default': { 'csp': "script-src * 'unsafe-inline'; referrer default",
          'expected': {  'sameorigin': 'full',
                        'crossorigin': 'full',
                          'downgrade': 'none' }},

  'origin':  { 'csp': "script-src * 'unsafe-inline'; referrer origin",
          'expected': {  'sameorigin': 'origin',
                        'crossorigin': 'origin',
                          'downgrade': 'origin' }},

  'origin-when-cross-origin':  { 'csp': "script-src * 'unsafe-inline'; referrer origin-when-cross-origin",
          'expected': {  'sameorigin': 'full',
                        'crossorigin': 'origin',
                          'downgrade': 'origin' }},

  'unsafe-url':  { 'csp': "script-src * 'unsafe-inline'; referrer unsafe-url",
          'expected': {  'sameorigin': 'full',
                        'crossorigin': 'full',
                          'downgrade': 'full' }},

  'none':   { 'csp': "script-src * 'unsafe-inline'; referrer no-referrer",
          'expected': {  'sameorigin': 'none',
                        'crossorigin': 'none',
                          'downgrade': 'none' }},

  // referrer delivered through CSPRO should be ignored
  'ignore-cspro':  { 'cspro': "script-src * 'unsafe-inline'; referrer origin",
          'expected': {  'sameorigin': 'full',
                        'crossorigin': 'full',
                          'downgrade': 'none' }},

  // referrer delivered through CSPRO should be ignored
  'ignore-cspro2':   { 'csp'  : "script-src * 'unsafe-inline'; referrer no-referrer",
                       'cspro': "script-src * 'unsafe-inline'; referrer origin",
         'expected': {  'sameorigin': 'none',
                        'crossorigin': 'none',
                          'downgrade': 'none' }},
  };

var referrerDirectiveTests = {
  // called via postMessage when one of the iframes is done running.
  onIframeComplete: function(event) {
    try {
      var results = JSON.parse(event.data);
      ok(results.hasOwnProperty('id'), "'id' property required in posted message " + event.data);

      ok(testData.hasOwnProperty(results['id']), "Test " + results['id'] + " must be expected.");

      // check all the various load types' referrers.
      var expected = testData[results['id']].expected;
      for (var t in expected) {
        is(results.results[t], expected[t],
          " referrer must match expected for " + t + " in " + results['id']);
      }
      testData[results['id']]['complete'] = true;

    } catch(e) {
      // fail -- should always be JSON
      ok(false, "failed to parse posted message + " + event.data);
      // have to end as well since not all messages were valid.
      SimpleTest.finish();
    }

    referrerDirectiveTests.checkForCompletion();
  },

  // checks to see if all the parallel tests are done and validates results.
  checkForCompletion: function() {
    for (var id in testData) {
      if (!testData[id].hasOwnProperty('complete')) {
        return;
      }
    }
    SimpleTest.finish();
  }
};

SimpleTest.waitForExplicitFinish();
// have to disable mixed content blocking to test https->http referrers.
SpecialPowers.pushPrefEnv({
    'set': [['security.mixed_content.block_active_content',   false],
            ['security.mixed_content.block_display_content',  false],
    ]
    },
    function() {
      // each of the iframes we create will call us back when its contents are loaded.
      window.addEventListener("message", referrerDirectiveTests.onIframeComplete.bind(window), false);

      // one iframe created for each test case
      for (var id in testData) {
        var elt = document.createElement("iframe");
        var src = "https://example.com/tests/dom/security/test/csp/file_testserver.sjs?id=" + id;
        if (testData[id]['csp']) {
          src += "&csp=" + escape(testData[id]['csp']);
        }
        if (testData[id]['cspro']) {
          src += "&cspro=" + escape(testData[id]['cspro']);
        }
        src += "&file=tests/dom/security/test/csp/file_referrerdirective.html";
        elt.src = src;
        document.getElementById("content").appendChild(elt);
      }
    });
</script>
</pre>
</body>
</html>