summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/dom-level0/test_setting_document.domain_idn.html
blob: b2e36dbbfa840ef72f039868ffd9b48072c1a1c2 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Setting document.domain and IDN</title>
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
  
</div>

<!--

This testing all gets a bit complicated here; the problem is that our
document.domain implementation will do a suffix comparison of the value to which
it's being set against the current URI's base domain (where "base domain" is
defined as the effective TLD plus one; see nsIEffectiveTLDService.idl).  Seems
simple enough, right?  Wrong.

The problem, as usual, is IDN.  Our current, wholly-inadequate solution to
preventing Unicode domain-name spoofing is done at the level of the URL
implementation, not at the presentation level.  However, the value of the
base domain for the current URI is always calculated in punycode; if the
provided domain is one which is whitelisted, we'll get an IDN name and the
suffix-comparison will fail.  Nice great big mess, huh?

Anyway: "test" currently fits the bill as a TLD which is not whitelisted, while
"δοκιμή" (the Greek IDN TLD for "test") fits the bill as a TLD which is
whitelisted.  RFC 2606 reserves "test" for DNS testing, so nobody's going to
clamor for it to be whitelisted any time soon.  The latter is as of February
2008 undergoing testing for IDN TLDs, and it's at least temporarily whitelisted
for now.  Once the testing period ends the latter's probably going to be
un-whitelisted, so we're going to have to do a careful bit of stepping to ensure
that in the future this test tests what it was intended to test (and, until
bug 414090 is fixed, that it doesn't break when the Greek TLD is
un-whitelisted).

After bug 722299 the IDN whitelist is expected to go away (bug
843689), but bug 414090 still applies, mutatis mutandis. The test has
been changed to use exaмple.test instead (with a Cyrillic м), which
will fail the mixed-script tests and use punycode.
-->

<div>
<h2>Whitelisted</h2>
<iframe name="idnKidWhitelist" src="http://sub1.παράδειγμα.δοκιμή/tests/dom/tests/mochitest/dom-level0/idn_child.html?idn-whitelist"></iframe>
<iframe name="punycodeKidWhitelist" src="http://sub1.παράδειγμα.δοκιμή/tests/dom/tests/mochitest/dom-level0/idn_child.html?punycode-whitelist"></iframe>
</div>

<div>
<h2>Not whitelisted</h2>
<iframe name="idnKidNoWhitelist" src="http://sub1.exaмple.test/tests/dom/tests/mochitest/dom-level0/idn_child.html?idn-nowhitelist"></iframe>
<iframe name="punycodeKidNoWhitelist" src="http://sub1.exaмple.test/tests/dom/tests/mochitest/dom-level0/idn_child.html?punycode-nowhitelist"></iframe>
</div>

<pre id="test">
<script class="testbody" type="application/javascript">

SimpleTest.waitForExplicitFinish();

var gotIDNNoWhitelist = false;
var gotPunycodeNoWhitelist = false;
var gotIDNWhitelist = false;
var gotPunycodeWhitelist = false;

var whitelistRegex =
  new RegExp("^http://sub1\\.παράδειγμα\\.δοκιμή/tests/dom/tests/" +
             "mochitest/dom-level0/idn_child\\.html\\?(.+)$");

var noWhitelistRegex =
  new RegExp("^http://sub1\\.exaмple\\.test/tests/dom/tests/" +
             "mochitest/dom-level0/idn_child\\.html\\?(.+)$");

var state = 0;

var messages =
  [
   "idn-whitelist",
   "punycode-whitelist",
   "idn-nowhitelist",
   "punycode-nowhitelist",
  ];


function receiveMessage(evt)
{
  var origin = evt.origin;
  var match;
  if (/test$/.test(origin))
  {
    // XXX bug 414090
    // The value of MessageEvent.origin with postMessage *should* always be IDN;
    // unfortunately, given our current setup for dealing with Unicode-based
    // domain-name spoofing, whether a domain is in the safe-for-IDN whitelist
    // affects the value of this property (likewise for window.location,
    // document.location, document.domain, and probably a slew of other
    // things).  :-(
    //
    // These two tests should illustrate what currently happens and what should
    // happen once bug 414090 is fixed.
    todo_is(evt.origin, "http://sub1.exaмple.test", "wrong sender");
    todo_isnot(evt.origin, "http://sub1.xn--exaple-kqf.test", "wrong sender");
  }
  else
  {
    // We're receiving data from the Greek IDN name; since that TLD is
    // whitelisted for now, the domain we get isn't going to be punycoded.
    is(evt.origin, "http://sub1.παράδειγμα.δοκιμή", "wrong sender");
  }

  is(messages[state] + "-response", evt.data.split(" ")[0],
     "unexpected data: " + evt.data);

  switch (messages[state])
  {
    case "idn-whitelist":
      gotIDNWhitelist = true;
      ok(evt.source === window.frames.idnKidWhitelist, "wrong source");
      is(evt.data, "idn-whitelist-response", "wrong response for IDN");
      break;

    case "punycode-whitelist":
      gotPunycodeWhitelist = true;
      ok(evt.source === window.frames.punycodeKidWhitelist, "wrong source");
      is(evt.data, "punycode-whitelist-response", "wrong response for punycode");
      break;

    case "idn-nowhitelist":
      gotIDNNoWhitelist = true;
      ok(evt.source === window.frames.idnKidNoWhitelist, "wrong source");
      is(evt.data, "idn-nowhitelist-response", "wrong response for IDN");
      break;

    case "punycode-nowhitelist":
      gotPunycodeNoWhitelist = true;
      ok(evt.source === window.frames.punycodeKidNoWhitelist, "wrong source");
      is(evt.data, "punycode-nowhitelist-response", "wrong response for punycode");
      break;

    default:
      ok(false, "unreached");
      break;
  }

  state++;
}

function run()
{
  var target = window.frames.idnKidWhitelist;
  target.postMessage("idn-whitelist", "http://sub1.παράδειγμα.δοκιμή");

  // Double-timeouts account for 1) delay for message to be received by target
  // window and 2) delay for response from target window to be received by this
  // window.

  setTimeout(function()
  {
    setTimeout(function()
    {
      ok(gotIDNWhitelist, "IDN whitelist message not received");

      var target = window.frames.punycodeKidWhitelist;
      target.postMessage("punycode-whitelist", "http://sub1.παράδειγμα.δοκιμή");

      setTimeout(function()
      {
        setTimeout(function()
        {
          ok(gotPunycodeWhitelist, "punycode whitelist message not received");

          var target = window.frames.idnKidNoWhitelist;
          target.postMessage("idn-nowhitelist", "http://sub1.exaмple.test");

          setTimeout(function()
          {
            setTimeout(function()
            {
              ok(gotIDNNoWhitelist, "IDN no-whitelist message not received");
    
              var target = window.frames.punycodeKidNoWhitelist;
              target.postMessage("punycode-nowhitelist",
                                 "http://sub1.exaмple.test");

              setTimeout(function()
              {
                setTimeout(function()
                {
                  ok(gotPunycodeNoWhitelist,
                     "punycode no-whitelist message not received");

                  SimpleTest.finish();
                }, 0);
              }, 0);
            }, 0);
          }, 0);
        }, 0);
      }, 0);
    }, 0);
  }, 0);
}

window.addEventListener("message", receiveMessage, false);
window.addEventListener("load", run, false);
</script>
</pre>
</body>
</html>