| OLD | NEW |
| (Empty) | |
| 1 |
| 2 /** |
| 3 * This test checks the Secure Context state of documents for various |
| 4 * permutations of document URI types and loading methods. |
| 5 * |
| 6 * The hierarchy that is tested is: |
| 7 * |
| 8 * creator-doc > createe-doc |
| 9 * |
| 10 * The creator-doc is one of: |
| 11 * |
| 12 * http: |
| 13 * https: |
| 14 * |
| 15 * The createe-doc is loaded as either a: |
| 16 * |
| 17 * popup |
| 18 * iframe |
| 19 * sandboxed-iframe |
| 20 * |
| 21 * into which we load and test: |
| 22 * |
| 23 * http: |
| 24 * https: |
| 25 * blob: |
| 26 * javascript: |
| 27 * about:blank |
| 28 * initial about:blank |
| 29 * srcdoc |
| 30 * |
| 31 * TODO once web-platform-tests supports it: |
| 32 * - test http://localhost |
| 33 * - test file: |
| 34 * |
| 35 * TODO once https://github.com/w3c/webappsec-secure-contexts/issues/26 is resol
ved |
| 36 * - test data: |
| 37 */ |
| 38 |
| 39 |
| 40 setup({explicit_done:true}); |
| 41 |
| 42 |
| 43 const host_and_dirname = location.host + |
| 44 location.pathname.substr(0, location.pathname.lastIndex
Of("/") + 1); |
| 45 |
| 46 |
| 47 // Flags to indicate where document types should be loaded for testing: |
| 48 const eLoadInPopup = (1 << 0); |
| 49 const eLoadInUnsandboxedIframe = (1 << 1); |
| 50 const eLoadInSandboxedIframe = (1 << 2); |
| 51 const eLoadInEverything = eLoadInPopup | eLoadInUnsandboxedIframe | eLoad
InSandboxedIframe; |
| 52 |
| 53 // Flags indicating if a document type is expected to be a Secure Context: |
| 54 const eSecureNo = 1; |
| 55 const eSecureIfCreatorSecure = 2; |
| 56 |
| 57 // Flags indicating how the result of a test is obtained: |
| 58 const eResultFromPostMessage = 1; |
| 59 const eResultFromExaminationOnLoad = 2; |
| 60 const eResultFromExaminationSync = 3; |
| 61 |
| 62 |
| 63 const loadTypes = [ |
| 64 new LoadType("an http: URI", |
| 65 eLoadInEverything, |
| 66 http_dir + "postMessage-helper.html", |
| 67 eSecureNo, |
| 68 eResultFromPostMessage), |
| 69 new LoadType("an https: URI", |
| 70 eLoadInEverything, |
| 71 https_dir + "postMessage-helper.https.html", |
| 72 eSecureIfCreatorSecure, |
| 73 eResultFromPostMessage), |
| 74 new LoadType("a blob: URI", |
| 75 eLoadInEverything, |
| 76 URL.createObjectURL(new Blob(["<script>(opener||parent).postMessa
ge(isSecureContext, '*')</script>"])), |
| 77 eSecureIfCreatorSecure, |
| 78 eResultFromPostMessage), |
| 79 new LoadType("a srcdoc", |
| 80 // popup not relevant: |
| 81 eLoadInUnsandboxedIframe | eLoadInSandboxedIframe, |
| 82 "<script>(opener||parent).postMessage(isSecureContext, '*')</scri
pt>", |
| 83 eSecureIfCreatorSecure, |
| 84 eResultFromPostMessage), |
| 85 new LoadType("a javascript: URI", |
| 86 // can't load in sandbox: |
| 87 eLoadInUnsandboxedIframe | eLoadInPopup, |
| 88 "javascript:(opener||parent).postMessage(isSecureContext, '*')", |
| 89 eSecureIfCreatorSecure, |
| 90 eResultFromPostMessage), |
| 91 new LoadType("about:blank", |
| 92 // can't obtain state if sandboxed: |
| 93 eLoadInUnsandboxedIframe | eLoadInPopup, |
| 94 "about:blank", |
| 95 eSecureIfCreatorSecure, |
| 96 eResultFromExaminationOnLoad), |
| 97 new LoadType("initial about:blank", |
| 98 // can't obtain state if sandboxed: |
| 99 eLoadInUnsandboxedIframe | eLoadInPopup, |
| 100 "about:blank", // we don't wait for this to load, so whatever |
| 101 eSecureIfCreatorSecure, |
| 102 eResultFromExaminationSync), |
| 103 ]; |
| 104 |
| 105 const loadTargets = [ |
| 106 new LoadTarget("an iframe", eLoadInUnsandboxedIframe), |
| 107 new LoadTarget("a sandboxed iframe", eLoadInSandboxedIframe), |
| 108 new LoadTarget("a popup", eLoadInPopup), |
| 109 ]; |
| 110 |
| 111 |
| 112 function LoadType(description, loadInFlags, uri, expectedSecureFlag, resultFrom)
{ |
| 113 this.desc = description; |
| 114 this.loadInFlags = loadInFlags; |
| 115 this.uri = uri; |
| 116 this.expectedSecureFlag = expectedSecureFlag; |
| 117 this.resultFrom = resultFrom; |
| 118 } |
| 119 |
| 120 |
| 121 function LoadTarget(description, loadInFlag) { |
| 122 this.desc = description; |
| 123 this.loadInFlag = loadInFlag; |
| 124 } |
| 125 |
| 126 LoadTarget.prototype.open = function(loadType) { |
| 127 let loadTarget = this; |
| 128 this.currentTest.step(function() { |
| 129 assert_true((loadTarget.loadInFlag & loadType.loadInFlags) != 0, |
| 130 loadType.desc + " cannot be tested in " + loadTarget.desc); |
| 131 }); |
| 132 if (this.loadInFlag == eLoadInUnsandboxedIframe) { |
| 133 let iframe = document.createElement("iframe"); |
| 134 document.body.appendChild(iframe); |
| 135 iframe[loadType.desc == "a srcdoc" ? "srcdoc" : "src"] = loadType.uri; |
| 136 return iframe; |
| 137 } |
| 138 if (this.loadInFlag == eLoadInSandboxedIframe) { |
| 139 let iframe = document.body.appendChild(document.createElement("iframe")); |
| 140 iframe.setAttribute("sandbox", "allow-scripts"); |
| 141 iframe[loadType.desc == "a srcdoc" ? "srcdoc" : "src"] = loadType.uri; |
| 142 return iframe; |
| 143 } |
| 144 if (this.loadInFlag == eLoadInPopup) { |
| 145 return window.open(loadType.uri); |
| 146 } |
| 147 this.currentTest.step(function() { |
| 148 assert_unreached("Unknown load type flag: " + loadInFlags); |
| 149 }); |
| 150 return null; |
| 151 } |
| 152 |
| 153 LoadTarget.prototype.close = function(domTarget) { |
| 154 if (this.loadInFlag == eLoadInUnsandboxedIframe || |
| 155 this.loadInFlag == eLoadInSandboxedIframe) { |
| 156 domTarget.remove(); |
| 157 return; |
| 158 } |
| 159 if (this.loadInFlag == eLoadInPopup) { |
| 160 domTarget.close(); |
| 161 return; |
| 162 } |
| 163 this.currentTest.step(function() { |
| 164 assert_unreached("Unknown load type flag: " + loadInFlags); |
| 165 }); |
| 166 } |
| 167 |
| 168 LoadTarget.prototype.load_and_get_result_for = function(loadType) { |
| 169 if (!(loadType.loadInFlags & this.loadInFlag)) { |
| 170 return Promise.reject("not applicable"); |
| 171 } |
| 172 if (!(this.loadInFlag & eLoadInPopup) && |
| 173 location.protocol == "https:" && |
| 174 loadType.uri.substr(0,5) == "http:") { |
| 175 // Mixed content blocker will prevent this load |
| 176 return Promise.reject("not applicable"); |
| 177 } |
| 178 this.currentTest = async_test("Test Window.isSecureContext in " + this.desc + |
| 179 " loading " + loadType.desc) |
| 180 if (loadType.resultFrom == eResultFromExaminationSync) { |
| 181 let domTarget = this.open(loadType); |
| 182 let result = domTarget instanceof Window ? |
| 183 domTarget.isSecureContext : domTarget.contentWindow.isSecureContext; |
| 184 this.close(domTarget); |
| 185 return Promise.resolve(result); |
| 186 } |
| 187 let target = this; |
| 188 if (loadType.resultFrom == eResultFromExaminationOnLoad) { |
| 189 return new Promise(function(resolve, reject) { |
| 190 function handleLoad(event) { |
| 191 let result = domTarget instanceof Window ? |
| 192 domTarget.isSecureContext : domTarget.contentWindow.isSecureContex
t; |
| 193 domTarget.removeEventListener("load", handleLoad); |
| 194 target.close(domTarget); |
| 195 resolve(result); |
| 196 } |
| 197 let domTarget = target.open(loadType); |
| 198 domTarget.addEventListener("load", handleLoad, false); |
| 199 }); |
| 200 } |
| 201 if (loadType.resultFrom == eResultFromPostMessage) { |
| 202 return new Promise(function(resolve, reject) { |
| 203 function handleMessage(event) { |
| 204 window.removeEventListener("message", handleMessage); |
| 205 target.close(domTarget); |
| 206 resolve(event.data); |
| 207 } |
| 208 window.addEventListener("message", handleMessage, false); |
| 209 let domTarget = target.open(loadType); |
| 210 }); |
| 211 } |
| 212 return Promise.reject("unexpected 'result from' type"); |
| 213 } |
| 214 |
| 215 |
| 216 let current_type_index = -1; |
| 217 let current_target_index = 0; |
| 218 |
| 219 function run_next_test() { |
| 220 current_type_index++; |
| 221 if (current_type_index >= loadTypes.length) { |
| 222 current_type_index = 0; |
| 223 current_target_index++; |
| 224 if (current_target_index >= loadTargets.length) { |
| 225 done(); |
| 226 return; // all test permutations complete |
| 227 } |
| 228 } |
| 229 let loadTarget = loadTargets[current_target_index]; |
| 230 let loadType = loadTypes[current_type_index]; |
| 231 loadTarget.load_and_get_result_for(loadType).then( |
| 232 function(value) { |
| 233 run_next_test_soon(); |
| 234 loadTarget.currentTest.step(function() { |
| 235 if (loadType.expectedSecureFlag == eSecureNo) { |
| 236 assert_false(value, loadType.desc + " in " + loadTarget.desc + " shoul
d not create a Secure Context"); |
| 237 } else if (loadType.expectedSecureFlag == eSecureIfCreatorSecure) { |
| 238 if (!window.isSecureContext) { |
| 239 assert_false(value, loadType.desc + " in " + loadTarget.desc + " sho
uld not create a Secure Context when its creator is not a Secure Context."); |
| 240 } else { |
| 241 assert_true(value, loadType.desc + " in " + loadTarget.desc + " shou
ld create a Secure Context when its creator is a Secure Context"); |
| 242 } |
| 243 } else { |
| 244 assert_unreached(loadType.desc + " - unknown expected secure flag: " +
expectedSecureFlag); |
| 245 } |
| 246 loadTarget.currentTest.done(); |
| 247 }); |
| 248 }, |
| 249 function(failReason) { |
| 250 run_next_test_soon(); |
| 251 if (failReason == "not applicable") { |
| 252 return; |
| 253 } |
| 254 loadTarget.currentTest.step(function() { |
| 255 assert_unreached(loadType.desc + " - got unexpected rejected promise"); |
| 256 }); |
| 257 } |
| 258 ); |
| 259 } |
| 260 |
| 261 function run_next_test_soon() { |
| 262 setTimeout(run_next_test, 0); |
| 263 } |
| 264 |
| 265 function begin() { |
| 266 test(function() { |
| 267 if (location.protocol == "http:") { |
| 268 assert_false(isSecureContext, |
| 269 "http: creator should not be a Secure Context"); |
| 270 } else if (location.protocol == "https:") { |
| 271 assert_true(isSecureContext, |
| 272 "https: creator should be a Secure Context"); |
| 273 } else { |
| 274 assert_unreached("Unknown location.protocol"); |
| 275 } |
| 276 }); |
| 277 run_next_test(); |
| 278 } |
| 279 |
| OLD | NEW |