dangling-markup-mitigation.tentative.html (4669B)
1 <!DOCTYPE html> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <body> 5 <script> 6 function readableURL(url) { 7 return url.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t"); 8 } 9 10 var should_load = [ 11 `/images/green-1x1.png`, 12 `/images/gre\nen-1x1.png`, 13 `/images/gre\ten-1x1.png`, 14 `/images/gre\ren-1x1.png`, 15 `/images/green-1x1.png?img=<`, 16 `/images/green-1x1.png?img=<`, 17 `/images/green-1x1.png?img=%3C`, 18 `/images/gr\neen-1x1.png?img=%3C`, 19 `/images/gr\reen-1x1.png?img=%3C`, 20 `/images/gr\teen-1x1.png?img=%3C`, 21 `/images/green-1x1.png?img= `, 22 `/images/gr\neen-1x1.png?img= `, 23 `/images/gr\reen-1x1.png?img= `, 24 `/images/gr\teen-1x1.png?img= `, 25 ]; 26 should_load.forEach(url => async_test(t => { 27 fetch(url) 28 .then(t.step_func_done(r => { 29 assert_equals(r.status, 200); 30 })) 31 .catch(t.unreached_func("Fetch should succeed.")); 32 }, "Fetch: " + readableURL(url))); 33 34 var should_block = [ 35 `/images/gre\nen-1x1.png?img=<`, 36 `/images/gre\ren-1x1.png?img=<`, 37 `/images/gre\ten-1x1.png?img=<`, 38 `/images/green-1x1.png?<\n=block`, 39 `/images/green-1x1.png?<\r=block`, 40 `/images/green-1x1.png?<\t=block`, 41 ]; 42 should_block.forEach(url => async_test(t => { 43 fetch(url) 44 .then(t.unreached_func("Fetch should fail.")) 45 .catch(t.step_func_done()); 46 }, "Fetch: " + readableURL(url))); 47 48 49 // For each of the following tests, we'll inject a frame containing the HTML we'd like to poke at 50 // as a `srcdoc` attribute. Because we're injecting markup via `srcdoc`, we need to entity-escape 51 // the content we'd like to treat as "raw" (e.g. `\n` => ` `, `<` => `<`), and 52 // double-escape the "escaped" content. 53 var rawBrace = "<"; 54 var escapedBrace = "&lt;"; 55 var rawNewline = " "; 56 var escapedNewline = "&#10;"; 57 58 function appendFrameAndGetElement(test, frame) { 59 return new Promise((resolve, reject) => { 60 frame.onload = test.step_func(_ => { 61 frame.onload = null; 62 resolve(frame.contentDocument.querySelector('#dangling')); 63 }); 64 document.body.appendChild(frame); 65 }); 66 } 67 68 function assert_img_loaded(test, frame) { 69 appendFrameAndGetElement(test, frame) 70 .then(test.step_func_done(img => { 71 assert_equals(img.naturalHeight, 1, "Height"); 72 frame.remove(); 73 })); 74 } 75 76 function assert_img_not_loaded(test, frame) { 77 appendFrameAndGetElement(test, frame) 78 .then(test.step_func_done(img => { 79 assert_equals(img.naturalHeight, 0, "Height"); 80 assert_equals(img.naturalWidth, 0, "Width"); 81 })); 82 } 83 84 function createFrame(markup) { 85 var i = document.createElement('iframe'); 86 i.srcdoc = `${markup}sekrit`; 87 return i; 88 } 89 90 // The following resources should not be blocked, as their URLs do not contain both a `\n` and `<` 91 // character in the body of the URL. 92 var should_load = [ 93 // Brace alone doesn't block: 94 `<img id="dangling" src="/images/green-1x1.png?img=${rawBrace}b">`, 95 96 // Newline alone doesn't block: 97 `<img id="dangling" src="/images/green-1x1.png?img=${rawNewline}b">`, 98 99 // Entity-escaped characters don't trigger blocking: 100 `<img id="dangling" src="/images/green-1x1.png?img=${escapedNewline}b">`, 101 `<img id="dangling" src="/images/green-1x1.png?img=${escapedBrace}b">`, 102 `<img id="dangling" src="/images/green-1x1.png?img=${escapedNewline}b${escapedBrace}c">`, 103 104 // Leading and trailing whitespace is stripped: 105 ` 106 <img id="dangling" src=" 107 /images/green-1x1.png?img= 108 "> 109 `, 110 ` 111 <img id="dangling" src=" 112 /images/green-1x1.png?img=${escapedBrace} 113 "> 114 `, 115 ` 116 <img id="dangling" src=" 117 /images/green-1x1.png?img=${escapedNewline} 118 "> 119 `, 120 ]; 121 122 should_load.forEach(markup => { 123 async_test(t => { 124 var i = createFrame(`${markup} <element attr="" another=''>`); 125 assert_img_loaded(t, i); 126 }, readableURL(markup)); 127 }); 128 129 // The following resources should be blocked, as their URLs contain both `\n` and `<` characters: 130 var should_block = [ 131 `<img id="dangling" src="/images/green-1x1.png?img=${rawNewline}${rawBrace}b">`, 132 `<img id="dangling" src="/images/green-1x1.png?img=${rawBrace}${rawNewline}b">`, 133 ` 134 <img id="dangling" src="/images/green-1x1.png?img= 135 ${rawBrace} 136 ${rawNewline}b 137 "> 138 `, 139 ]; 140 141 should_block.forEach(markup => { 142 async_test(t => { 143 var i = createFrame(`${markup}`); 144 assert_img_not_loaded(t, i); 145 }, readableURL(markup)); 146 }); 147 </script>