Reviewed by Darin and Sam.
- test cases for <rdar://problem/
5395213> cross-domain access to individual components of location object should be denied.
* http/tests/security/cross-frame-access-location-expected.txt: This test's results changed, there are more debug messages due to access being legitimately denied.
The remainder are new tests and support:
* http/tests/security/resources/xss-DENIED-assign-location-hash-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-host-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-host-failure.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-hostname-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-hostname-failure.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-nonstandardProperty-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-pathname-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-pathname-failure.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-protocol-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-protocol-failure.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-reload-attacker.html: Added.
* http/tests/security/resources/xss-DENIED-assign-location-search-attacker.html: Added.
* http/tests/security/xss-DENIED-assign-location-hash-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-hash.html: Added.
* http/tests/security/xss-DENIED-assign-location-host-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-host.html: Added.
* http/tests/security/xss-DENIED-assign-location-hostname-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-hostname.html: Added.
* http/tests/security/xss-DENIED-assign-location-nonstandardProperty-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-nonstandardProperty.html: Added.
* http/tests/security/xss-DENIED-assign-location-pathname-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-pathname.html: Added.
* http/tests/security/xss-DENIED-assign-location-protocol-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-protocol.html: Added.
* http/tests/security/xss-DENIED-assign-location-reload-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-reload.html: Added.
* http/tests/security/xss-DENIED-assign-location-search-expected.txt: Added.
* http/tests/security/xss-DENIED-assign-location-search.html: Added.
WebCore:
Reviewed by Darin and Sam.
<rdar://problem/
5395213> cross-domain access to individual components of location object should be denied.
* bindings/js/kjs_window.cpp:
(KJS::Location::put): Add the appropriate cross-domain access checks.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25028
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-08-12 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin and Sam.
+
+ - test cases for <rdar://problem/5395213> cross-domain access to individual components of location object should be denied.
+
+ * http/tests/security/cross-frame-access-location-expected.txt: This test's results changed, there are more debug messages due to access being legitimately denied.
+
+ The remainder are new tests and support:
+
+ * http/tests/security/resources/xss-DENIED-assign-location-hash-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-host-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-host-failure.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-hostname-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-hostname-failure.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-nonstandardProperty-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-pathname-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-pathname-failure.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-protocol-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-protocol-failure.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-reload-attacker.html: Added.
+ * http/tests/security/resources/xss-DENIED-assign-location-search-attacker.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-hash-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-hash.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-host-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-host.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-hostname-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-hostname.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-nonstandardProperty-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-nonstandardProperty.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-pathname-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-pathname.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-protocol-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-protocol.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-reload-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-reload.html: Added.
+ * http/tests/security/xss-DENIED-assign-location-search-expected.txt: Added.
+ * http/tests/security/xss-DENIED-assign-location-search.html: Added.
+
2007-08-12 Darin Adler <darin@apple.com>
Reviewed by Maciej.
CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-get-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-location.html. Domains, protocols and ports must match.
+
----- tests for getting/setting window.location and its properties -----
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.hash = "hax0red";
+</script>
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.host = "localhost:8000/security/resources/xss-DENIED-assign-location-host-failure.html?";
+</script>
--- /dev/null
+<script>
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+
+FAIL: cross-site assignment of location.host was allowed.
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.hostname = "localhost:8000/security/resources/xss-DENIED-assign-location-hostname-failure.html?";
+</script>
--- /dev/null
+<script>
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+
+FAIL: cross-site assignment of location.hostname was allowed.
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.nonstandardProperty = "hax0red";
+</script>
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.pathname = "/security/resources/xss-DENIED-assign-location-pathname-failure.html";
+</script>
--- /dev/null
+<script>
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+
+FAIL: cross-site assignment of location.pathname was allowed.
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.protocol = "http://localhost:8000/security/resources/xss-DENIED-assign-location-protocol-failure.html?";
+</script>
--- /dev/null
+<script>
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+
+FAIL: cross-site assignment of location.protocol was allowed.
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.replace = "hax0red";
+</script>
--- /dev/null
+<script>
+var victim = parent;
+
+victim.location.search = "?hax0red";
+</script>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-hash.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-hash-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.hash not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function finish()
+{
+ if (location.hash.length == 0)
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.hash not allowed";
+ else
+ document.getElementById("console").innerHTML = "FAIL: cross-site assignment of location.hash was allowed!";
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="finish()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-hash-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-host.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-host-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.host not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function success()
+{
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.host not allowed";
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="success()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-host-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-hostname.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-hostname-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.hostname not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function success()
+{
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.hostname not allowed";
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="success()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-hostname-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-nonstandardProperty.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-nonstandardProperty-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.nonstandardProperty not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function finish()
+{
+ if (location.nonstandardProperty != "hax0red")
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.nonstandardProperty not allowed";
+ else
+ document.getElementById("console").innerHTML = "FAIL: cross-site assignment of location.nonstandardProperty was allowed!";
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="finish()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-nonstandardProperty-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-pathname.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-pathname-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.pathname not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function success()
+{
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.pathname not allowed";
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="success()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-pathname-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-protocol.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-protocol-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.protocol not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function success()
+{
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.protocol not allowed";
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="success()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-protocol-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-reload.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-reload-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.replace not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function finish()
+{
+ if (location.reload != "hax0red")
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.replace not allowed";
+ else
+ document.getElementById("console").innerHTML = "FAIL: cross-site assignment of location.replace was allowed!";
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="finish()">
+
+ <iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-reload-attacker.html"></iframe>
+
+<div id="console"></div>
+</body>
+</html>
--- /dev/null
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-assign-location-search.html from frame with URL http://localhost:8000/security/resources/xss-DENIED-assign-location-search-attacker.html. Domains, protocols and ports must match.
+
+
+PASS: cross-site assignment of location.search not allowed
--- /dev/null
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function finish()
+{
+ if (location.search.length == 0)
+ document.getElementById("console").innerHTML = "PASS: cross-site assignment of location.search not allowed";
+ else
+ document.getElementById("console").innerHTML = "FAIL: cross-site assignment of location.search was allowed!";
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+
+<body onload="finish()">
+
+<script>
+if (location.search == 0) {
+ document.write('<iframe src="http://localhost:8000/security/resources/xss-DENIED-assign-location-search-attacker.html"></iframe>');
+}
+</script>
+
+<div id="console"></div>
+</body>
+</html>
+2007-08-12 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin and Sam.
+
+ <rdar://problem/5395213> cross-domain access to individual components of location object should be denied.
+
+ * bindings/js/kjs_window.cpp:
+ (KJS::Location::put): Add the appropriate cross-domain access checks.
+
2007-08-12 Darin Adler <darin@apple.com>
Reviewed by John Sullivan.
DeprecatedString str = v->toString(exec);
KURL url = m_frame->loader()->url();
+ const Window* window = Window::retrieveWindow(m_frame);
+ bool sameDomainAccess = window && window->isSafeScript(exec);
+
const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
- if (entry)
- switch (entry->value) {
- case Href: {
- Frame* p = Window::retrieveActive(exec)->impl()->frame();
- if ( p )
- url = p->loader()->completeURL(str).url();
- else
- url = str;
- break;
- }
- case Hash: {
- if (str.startsWith("#"))
- str = str.mid(1);
- if (url.ref() == str)
+ if (entry) {
+ // cross-domain access to the location is allowed when assigning the whole location,
+ // but not when assigning the individual pieces, since that might inadvertently
+ // disclose other parts of the original location.
+ if (entry->value != Href && !sameDomainAccess)
return;
- url.setRef(str);
- break;
- }
- case Host: {
- url.setHostAndPort(str);
- break;
- }
- case Hostname:
- url.setHost(str);
- break;
- case Pathname:
- url.setPath(str);
- break;
- case Port:
- url.setPort(str.toUInt());
- break;
- case Protocol:
- url.setProtocol(str);
- break;
- case Search:
- url.setQuery(str);
- break;
- default:
- // Disallow changing other properties in LocationTable. e.g., "window.location.toString = ...".
- // <http://bugs.webkit.org/show_bug.cgi?id=12720>
+ switch (entry->value) {
+ case Href: {
+ Frame* frame = Window::retrieveActive(exec)->impl()->frame();
+ if (frame)
+ url = frame->loader()->completeURL(str).url();
+ else
+ url = str;
+ break;
+ }
+ case Hash: {
+ if (str.startsWith("#"))
+ str = str.mid(1);
+
+ if (url.ref() == str)
+ return;
+
+ url.setRef(str);
+ break;
+ }
+ case Host: {
+ url.setHostAndPort(str);
+ break;
+ }
+ case Hostname:
+ url.setHost(str);
+ break;
+ case Pathname:
+ url.setPath(str);
+ break;
+ case Port:
+ url.setPort(str.toUInt());
+ break;
+ case Protocol:
+ url.setProtocol(str);
+ break;
+ case Search:
+ url.setQuery(str);
+ break;
+ default:
+ // Disallow changing other properties in LocationTable. e.g., "window.location.toString = ...".
+ // <http://bugs.webkit.org/show_bug.cgi?id=12720>
+ return;
+ }
+ } else {
+ if (sameDomainAccess)
+ JSObject::put(exec, p, v, attr);
return;
- }
- else {
- JSObject::put(exec, p, v, attr);
- return;
}
- const Window* window = Window::retrieveWindow(m_frame);
Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
- if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
+ if (!url.url().startsWith("javascript:", false) || sameDomainAccess) {
bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
m_frame->loader()->scheduleLocationChange(url.url(), activeFrame->loader()->outgoingReferrer(), false, userGesture);
}