Commit 95cc1cb6 authored by Maciek Trzos's avatar Maciek Trzos Committed by Commit Bot

Refactored usage of XHR, added error handling.

- Added error handling as suggested in https://github.com/web-platform-tests/wpt/pull/12162
- changed XHR calls to FetchAPI
- changed async tests to Promise tests
- corrected the existing redirect tests and reported bug: crbug/872285
- removed Same-Site and Cross-Origin XSLT tests as they seemed to fail because loading
    cross origin xslt is not supported "Unsafe attempt to load URL from frame"
    (No idea why they passed before)
- added two test cases for multiple redirects. The idea is that the Sec-Metadata header
    should be "downgraded" to less secure and should carry the value to the end.
    If a cross-origin domain controls a redirect at any point of the redirect chain,
    then the final requests are potentially influenced by the attacker.
    - (Same-Origin -> Cross-Site -> Same-Origin -> Same-Origin) -> site=cross-site
    - (Same-Origin -> Same-Site -> Same-Origin -> Same-Origin) -> site=same-site

Change-Id: I591af1948cc1f16e3b5c44f51020149e43fc2746
Reviewed-on: https://chromium-review.googlesource.com/1193953
Commit-Queue: Maciek Trzos <mtrzos@google.com>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587556}
parent d909938c
<!DOCTYPE html> <!DOCTYPE html>
<html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos"> <link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
...@@ -43,62 +43,42 @@ ...@@ -43,62 +43,42 @@
</body> </body>
<script> <script>
document.fonts.ready.then(function () { document.fonts.ready.then(function () {
test_same_origin(); promise_test(t => {
test_same_site(); return new Promise((resolve, reject) => {
test_cross_site(); let key = "font-same-origin";
let expected = {"destination":"font", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
}); });
}, "Same-Origin font");
function test_same_origin(){ promise_test(t => {
var same_origin_test = async_test("Same-Origin font"); return new Promise((resolve, reject) => {
same_origin_test.step(function () { let key = "font-same-site";
key = "font-same-origin"; let expected = {"destination":"font", "site":"same-site"};
expected_same_origin = {"destination":"font", "site":"same-origin"}; fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
// Requests from the server the saved value of the Sec-Metadata header .then(text => assert_header_equals(text, expected))
same_origin_xhr = new XMLHttpRequest(); .then(_ => resolve())
same_origin_xhr.open("PUT", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); .catch(e => reject(e));
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
}); });
} }, "Same-Site font");
function test_same_site(){
var same_site_test = async_test("Same-Site font");
same_site_test.step(function () {
key = "font-same-site";
expected_same_site = {"destination":"font", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded promise_test(t => {
same_site_xhr.onreadystatechange = same_site_test.step_func(function () { return new Promise((resolve, reject) => {
verify_response(same_site_xhr, same_site_test, expected_same_site) let key = "font-cross-site";
let expected = {"destination":"font", "site":"cross-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
}); });
same_site_xhr.send(); }, "Cross-Site font");
});
}
function test_cross_site(){
var cross_site_test = async_test("Cross-Site font");
cross_site_test.step(function () {
key = "font-cross-site";
expected_cross_site = {"destination":"font", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
}); });
}
</script> </script>
</html>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-cross-site-same-origin";
let e = document.createElement('img');
e.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Cross-Site -> Same-Origin redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-cross-site-same-site";
let e = document.createElement('img');
e.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Cross-Site -> Same-Site redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-cross-site-cross-site";
let e = document.createElement('img');
e.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Cross-Site -> Cross-Site redirect");
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Cross-Site -> Cross-Site redirect");
cross_site_test.step(function () {
filename = "redirect-cross-site-cross-site";
expected_cross_site = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Cross-Site -> Same-Origin redirect");
same_origin_test.step(function () {
filename = "redirect-cross-site-same-origin";
expected_same_origin = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Cross-Site -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-cross-site-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Cross-Site -> Same-Site redirect");
same_site_test.step(function () {
filename = "redirect-cross-site-same-site";
expected_same_site = {"destination":"image", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>
This is a testharness.js-based test.
FAIL Same-Origin -> Cross-Site -> Same-Origin redirect assert_equals: site expected "cross-site" but got "same-origin"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-multiple-cross-site";
let e = document.createElement('img');
e.src = "https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=" +// same-origin
"https://{{hosts[alt][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=" +// cross-site
"https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;// same-origin
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin -> Cross-Site -> Same-Origin redirect");
</script>
This is a testharness.js-based test.
FAIL Same-Origin -> Same-Site -> Same-Origin redirect assert_equals: site expected "same-site" but got "same-origin"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-multiple-same-site";
let e = document.createElement('img');
e.src = "https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=" +// same-origin
"https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=" +// same-site
"https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;// same-origin
let expected = {"destination":"image", "site":"same-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin -> Same-Site -> Same-Origin redirect");
</script>
This is a testharness.js-based test.
PASS Same-Origin -> Same-Origin redirect
FAIL Same-Origin -> Same-Site redirect assert_equals: site expected "same-site" but got "same-origin"
FAIL Same-Origin -> Cross-Site redirect assert_equals: site expected "cross-site" but got "same-origin"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-origin-same-origin";
let e = document.createElement('img');
e.src = "/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"same-origin"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin -> Same-Origin redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-origin-same-site";
let e = document.createElement('img');
e.src = "/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"same-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin -> Same-Site redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-origin-cross-site";
let e = document.createElement('img');
e.src = "/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Origin -> Cross-Site redirect");
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Same-Origin -> Cross-Site redirect");
cross_site_test.step(function () {
filename = "redirect-same-origin-cross-site";
expected_cross_site = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Same-Origin -> Same-Origin redirect");
same_origin_test.step(function () {
filename = "redirect-same-origin-same-origin";
expected_same_origin = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Origin -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{host}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-origin-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Same-Origin -> Same-Site redirect");
same_site_test.step(function () {
filename = "redirect-same-origin-same-site";
expected_same_site = {"destination":"image", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + filename);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>
This is a testharness.js-based test.
PASS Same-Site -> Same-Origin redirect
PASS Same-Site -> Same-Site redirect
FAIL Same-Site -> Cross-Site redirect assert_equals: site expected "cross-site" but got "same-site"
Harness: the test ran to completion.
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script>
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-site-same-origin";
let e = document.createElement('img');
e.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"same-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Site -> Same-Origin redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-site-same-site";
let e = document.createElement('img');
e.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"same-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Site -> Same-Site redirect");
promise_test(t => {
return new Promise((resolve, reject) => {
let key = "redirect-same-site-cross-site";
let e = document.createElement('img');
e.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
let expected = {"destination":"image", "site":"cross-site"};
e.onload = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
e.onerror = e => {
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
document.body.appendChild(e);
})
}, "Same-Site -> Cross-Site redirect");
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Cross-Site -->
<img onload="test_cross_site()" onerror="test_cross_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-cross-site"></img>
</body>
<script>
function test_cross_site(){
var cross_site_test = async_test("Same-Site -> Cross-Site redirect");
cross_site_test.step(function () {
key = "redirect-same-site-cross-site";
expected_cross_site = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
cross_site_xhr = new XMLHttpRequest();
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () {
verify_response(cross_site_xhr, cross_site_test, expected_cross_site)
});
cross_site_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Same-Origin -->
<img onload="test_same_origin()" onerror="test_same_origin()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-origin"></img>
</body>
<script>
function test_same_origin(){
var same_origin_test = async_test("Same-Site -> Same-Origin redirect");
same_origin_test.step(function () {
key = "redirect-same-site-same-origin";
expected_same_origin = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_origin_xhr = new XMLHttpRequest();
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () {
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
}
</script>
<!DOCTYPE html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<body>
<!-- redirect Same-Site -> Same-Site -->
<img onload="test_same_site()" onerror="test_same_site()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/xhr/resources/redirect.py?location=https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=redirect-same-site-same-site"></img>
</body>
<script>
function test_same_site(){
var same_site_test = async_test("Same-Site -> Same-Site redirect");
same_site_test.step(function () {
key = "redirect-same-site-same-site";
expected_same_site = {"destination":"image", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header
same_site_xhr = new XMLHttpRequest();
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key);
// Async test step triggered when the response is loaded
same_site_xhr.onreadystatechange = same_site_test.step_func(function () {
verify_response(same_site_xhr, same_site_test, expected_same_site)
});
same_site_xhr.send();
});
}
</script>
...@@ -17,10 +17,3 @@ function assert_header_equals(value, expected) { ...@@ -17,10 +17,3 @@ function assert_header_equals(value, expected) {
assert_equals(result.target, expected.target, "target"); assert_equals(result.target, expected.target, "target");
assert_equals(result.site, expected.site, "site"); assert_equals(result.site, expected.site, "site");
} }
function verify_response(xhr, test, expected){
if (xhr.readyState === 4) {
assert_header_equals(xhr.responseText, expected);
test.done();
}
}
...@@ -12,5 +12,5 @@ def main(request, response): ...@@ -12,5 +12,5 @@ def main(request, response):
if (window.top != window) if (window.top != window)
window.top.postMessage(data, "*"); window.top.postMessage(data, "*");
</script> </script>
""" % json.dumps(request.headers["sec-metadata"]) """ % json.dumps(request.headers.get("Sec-Metadata", ""))
return headers, body return headers, body
...@@ -21,20 +21,23 @@ def main(request, response): ...@@ -21,20 +21,23 @@ def main(request, response):
if 'retrieve' in request.GET: if 'retrieve' in request.GET:
response.writer.write_status(200) response.writer.write_status(200)
response.writer.end_headers() response.writer.end_headers()
try:
header_value = request.server.stash.take(testId) header_value = request.server.stash.take(testId)
if header_value != None:
response.writer.write(header_value) response.writer.write(header_value)
except (KeyError, ValueError) as e:
response.writer.write("No header has been recorded")
pass
response.close_connection = True response.close_connection = True
## Record incoming Sec-Metadata header value ## Record incoming Sec-Metadata header value
else: else:
try:
## Return empty string as a default value ## ## Return empty string as a default value ##
header = request.headers.get("Sec-Metadata", "") header = request.headers.get("Sec-Metadata", "")
try:
request.server.stash.put(testId, header) request.server.stash.put(testId, header)
except KeyError: except KeyError:
## The header is already recorded ## The header is already recorded or it doesn't exist
pass pass
## Prevent the browser from caching returned responses and allow CORS ## ## Prevent the browser from caching returned responses and allow CORS ##
...@@ -61,6 +64,7 @@ def main(request, response): ...@@ -61,6 +64,7 @@ def main(request, response):
## Return a valid font content and Content-Type ## ## Return a valid font content and Content-Type ##
if key.startswith("font"): if key.startswith("font"):
response.headers.set("Content-Type", "application/x-font-ttf")
file = open("fonts/Ahem.ttf", "r") file = open("fonts/Ahem.ttf", "r")
font = file.read() font = file.read()
file.close() file.close()
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<script> <script>
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
window.addEventListener('load', function() { window.addEventListener('load', function() {
navigator.serviceWorker.register('/fetch/sec-metadata/resources/record-header.py?file=serviceworker-same-origin').then(function(registration) { navigator.serviceWorker.register('https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=serviceworker-same-origin').then(function(registration) {
test_same_origin(); test_same_origin();
// uninstall the serviceworker after the test // uninstall the serviceworker after the test
...@@ -32,20 +32,16 @@ ...@@ -32,20 +32,16 @@
<script> <script>
function test_same_origin(){ function test_same_origin(){
var same_origin_test = async_test("Same-Origin serviceworker"); promise_test(t => {
same_origin_test.step(function () { return new Promise((resolve, reject) => {
key = "serviceworker-same-origin"; let key = "serviceworker-same-origin";
expected_same_origin = {"destination":"serviceworker", "site":"same-origin"}; let expected = {"destination":"serviceworker", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
// Requests from the server the saved value of the Sec-Metadata header .then(response => response.text())
same_origin_xhr = new XMLHttpRequest(); .then(text => assert_header_equals(text, expected))
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); .then(_ => resolve())
.catch(e => reject(e));
// Async test step triggered when the response is loaded })
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () { })
verify_response(same_origin_xhr, same_origin_test, expected_same_origin)
});
same_origin_xhr.send();
});
} }
</script> </script>
...@@ -23,22 +23,18 @@ ...@@ -23,22 +23,18 @@
} }
function test_same_origin(){ function test_same_origin(){
var same_origin_test = async_test("Same-Origin sharedworker"); promise_test(t => {
same_origin_test.step(function () { return new Promise((resolve, reject) => {
key = "sharedworker-same-origin"; let key = "sharedworker-same-origin";
expected_same_origin = {"destination":"sharedworker", "site":"same-origin"}; let expected = {"destination":"sharedworker", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
same_origin_xhr = new XMLHttpRequest(); .then(response => response.text())
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); .then(text => assert_header_equals(text, expected))
.then(_ => resolve())
// Async test step triggered when the response is loaded .catch(e => reject(e));
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () { })
verify_response(same_origin_xhr, same_origin_test, expected_same_origin) }, "Same-Origin sharedworker")
});
same_origin_xhr.send();
});
} }
</script> </script>
<body></body> <body></body>
<!DOCTYPE html> <!DOCTYPE html>
<html>
<link rel="author" href="mtrzos@google.com" title="Maciek Trzos"> <link rel="author" href="mtrzos@google.com" title="Maciek Trzos">
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script> <script src=/fetch/sec-metadata/resources/helper.js></script>
<body></body>
<script> <script>
function test_same_origin() { promise_test(t => {
var same_origin_test = async_test("Same-Origin style"); return new Promise((resolve, reject) => {
same_origin_test.step(function () { let key = "style-same-origin";
key = "style-same-origin";
expected_same_origin = {"destination":"style", "site":"same-origin"};
// Requests from the server the saved value of the Sec-Metadata header let e = document.createElement('link');
same_origin_xhr = new XMLHttpRequest(); e.rel = "stylesheet";
same_origin_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); e.href = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"style", "site":"same-origin"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
// Async test step triggered when the response is loaded document.body.appendChild(e);
same_origin_xhr.onreadystatechange = same_origin_test.step_func(function () { })
verify_response(same_origin_xhr, same_origin_test, expected_same_origin) }, "Same-Origin style");
});
same_origin_xhr.send();
});
}
function test_same_site() { promise_test(t => {
var same_site_test = async_test("Same-Site style"); return new Promise((resolve, reject) => {
same_site_test.step(function () { let key = "style-same-site";
key = "style-same-site";
expected_same_site = {"destination":"style", "site":"same-site"};
// Requests from the server the saved value of the Sec-Metadata header let e = document.createElement('link');
same_site_xhr = new XMLHttpRequest(); e.rel = "stylesheet";
same_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); e.href = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"style", "site":"same-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
// Async test step triggered when the response is loaded document.body.appendChild(e);
same_site_xhr.onreadystatechange = same_site_test.step_func(function () { })
verify_response(same_site_xhr, same_site_test, expected_same_site) }, "Same-Site style");
});
same_site_xhr.send();
});
}
function test_cross_site() { promise_test(t => {
var cross_site_test = async_test("Cross-Site style"); return new Promise((resolve, reject) => {
cross_site_test.step(function () { let key = "style-cross-site";
key = "style-cross-site";
expected_cross_site = {"destination":"style", "site":"cross-site"};
// Requests from the server the saved value of the Sec-Metadata header let e = document.createElement('link');
cross_site_xhr = new XMLHttpRequest(); e.rel = "stylesheet";
cross_site_xhr.open("GET", "/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key); e.href = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=" + key;
e.onload = e => {
let expected = {"destination":"style", "site":"cross-site"};
fetch("/fetch/sec-metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(response => response.text())
.then(text => assert_header_equals(text, expected))
.then(_ => resolve())
.catch(e => reject(e));
};
// Async test step triggered when the response is loaded document.body.appendChild(e);
cross_site_xhr.onreadystatechange = cross_site_test.step_func(function () { })
verify_response(cross_site_xhr, cross_site_test, expected_cross_site) }, "Cross-Site style");
});
cross_site_xhr.send();
});
}
</script> </script>
<body> </html>
<!-- Same-Origin request -->
<link href="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-origin"
rel="stylesheet" onload="test_same_origin()" onerror="test_same_origin()">
<!-- Same-Site request -->
<link href="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-same-site"
rel="stylesheet" onload="test_same_site()" onerror="test_same_site()">
<!-- Cross-Site request -->
<link href="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/record-header.py?file=style-cross-site"
rel="stylesheet" onload="test_cross_site()" onerror="test_cross_site()">
</body>
This is a testharness.js-based test. This is a testharness.js-based test.
PASS Same-Origin xslt PASS Same-Origin xslt
FAIL Same-site xslt assert_not_equals: Empty Sec-Metadata header. got disallowed value "" FAIL Same-site xslt promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'trim' of undefined"
FAIL Cross-site xslt assert_not_equals: Empty Sec-Metadata header. got disallowed value "" FAIL Cross-site xslt promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'trim' of undefined"
Harness: the test ran to completion. Harness: the test ran to completion.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment