Commit 7a8fde5a authored by abarth@webkit.org's avatar abarth@webkit.org
Browse files

2010-04-02 Justin Schuh <jschuh@chromium.org>

        Reviewed by Alexey Proskuryakov.

        XHR allows arbitrary XSRF across domains
        https://bugs.webkit.org/show_bug.cgi?id=36843

        Added a one-line change to prevent bypassing the XDC check on
        synchronous preflighted requests. Added layout tests to cover
        variations of this problem.

        * http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-preflight-async-header-denied.html: Added.
        * http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-preflight-async-method-denied.html: Added.
        * http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-preflight-sync-header-denied.html: Added.
        * http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-preflight-sync-method-denied.html: Added.
        * http/tests/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php: Added.
2010-04-02  Justin Schuh  <jschuh@chromium.org>

        Reviewed by Alexey Proskuryakov.

        XHR allows arbitrary XSRF across domains
        https://bugs.webkit.org/show_bug.cgi?id=36843

        Added a one-line change to prevent bypassing the XDC check on
        synchronous preflighted requests. Added layout tests to cover
        variations of this problem.

        Tests: http/tests/xmlhttprequest/access-control-preflight-async-header-denied.html
               http/tests/xmlhttprequest/access-control-preflight-async-method-denied.html
               http/tests/xmlhttprequest/access-control-preflight-sync-header-denied.html
               http/tests/xmlhttprequest/access-control-preflight-sync-method-denied.html

        * loader/DocumentThreadableLoader.cpp:
        (WebCore::DocumentThreadableLoader::preflightFailure):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@57041 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 948358ba
2010-04-02 Justin Schuh <jschuh@chromium.org>
Reviewed by Alexey Proskuryakov.
XHR allows arbitrary XSRF across domains
https://bugs.webkit.org/show_bug.cgi?id=36843
Added a one-line change to prevent bypassing the XDC check on
synchronous preflighted requests. Added layout tests to cover
variations of this problem.
* http/tests/xmlhttprequest/access-control-preflight-async-header-denied-expected.txt: Added.
* http/tests/xmlhttprequest/access-control-preflight-async-header-denied.html: Added.
* http/tests/xmlhttprequest/access-control-preflight-async-method-denied-expected.txt: Added.
* http/tests/xmlhttprequest/access-control-preflight-async-method-denied.html: Added.
* http/tests/xmlhttprequest/access-control-preflight-sync-header-denied-expected.txt: Added.
* http/tests/xmlhttprequest/access-control-preflight-sync-header-denied.html: Added.
* http/tests/xmlhttprequest/access-control-preflight-sync-method-denied-expected.txt: Added.
* http/tests/xmlhttprequest/access-control-preflight-sync-method-denied.html: Added.
* http/tests/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php: Added.
2010-04-02 Andrew Scherkus <scherkus@chromium.org>
 
Reviewed by Eric Carlson and Eric Seidel.
......
<html>
<body>
<pre id='console'></pre>
<script type="text/javascript">
function log(message)
{
document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}
(function() {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=reset", false);
xhr.send("");
} catch(e) {
log("FAIL: Unable to reset server state: [" + e.message + "].");
return;
}
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php", false);
xhr.setRequestHeader("X-NON-STANDARD", "filler");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in first 'open'. [" + e.message + "].");
return;
}
xhr.onreadystatechange = function() {
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=complete", false);
try {
xhr.send("");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'send'. [" + e.message + "].");
}
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'open'. [" + e.message + "].");
}
log(xhr.responseText);
}
try {
xhr.send("");
log("FAIL: Cross-domain access allowed in first send without throwing an exception");
return;
} catch(e) {
// Eat the exception.
}
})();
</script>
</body>
</html>
<html>
<body>
<pre id='console'></pre>
<script type="text/javascript">
function log(message)
{
document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}
(function() {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=reset", false);
xhr.send("");
} catch(e) {
log("FAIL: Unable to reset server state: [" + e.message + "].");
return;
}
xhr = new XMLHttpRequest();
try {
xhr.open("DELETE", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php", false);
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in first 'open'. [" + e.message + "].");
return;
}
xhr.onreadystatechange = function() {
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=complete", false);
try {
xhr.send("");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'send'. [" + e.message + "].");
}
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'open'. [" + e.message + "].");
}
log(xhr.responseText);
}
try {
xhr.send("");
log("FAIL: Cross-domain access allowed in first send without throwing an exception");
return;
} catch(e) {
// Eat the exception.
}
})();
</script>
</body>
</html>
<html>
<body>
<pre id='console'></pre>
<script type="text/javascript">
function log(message)
{
document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}
(function() {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=reset", false);
xhr.send("");
} catch(e) {
log("FAIL: Unable to reset server state: [" + e.message + "].");
return;
}
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php", false);
xhr.setRequestHeader("X-NON-STANDARD", "filler");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in first 'open'. [" + e.message + "].");
return;
}
try {
xhr.send("");
log("FAIL: Cross-domain access allowed in first send without throwing an exception");
return;
} catch(e) {
// Eat the exception.
}
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=complete", false);
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'open'. [" + e.message + "].");
return;
}
try {
xhr.send("");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'send'. [" + e.message + "].");
return;
}
log(xhr.responseText);
})();
</script>
</body>
</html>
<html>
<body>
<pre id='console'></pre>
<script type="text/javascript">
function log(message)
{
document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}
(function() {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=reset", false);
xhr.send("");
} catch(e) {
log("FAIL: Unable to reset server state: [" + e.message + "].");
return;
}
xhr = new XMLHttpRequest();
try {
xhr.open("DELETE", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php", false);
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in first 'open'. [" + e.message + "].");
return;
}
try {
xhr.send("");
log("FAIL: Cross-domain access allowed in first send without throwing an exception");
return;
} catch(e) {
// Eat the exception.
}
xhr = new XMLHttpRequest();
try {
xhr.open("GET", "http://localhost:8000/xmlhttprequest/resources/access-control-preflight-denied-xsrf.php?state=complete", false);
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'open'. [" + e.message + "].");
return;
}
try {
xhr.send("");
} catch(e) {
log("FAIL: Exception thrown. Cross-domain access is not allowed in second 'send'. [" + e.message + "].");
return;
}
log(xhr.responseText);
})();
</script>
</body>
</html>
<?php
require_once '../../resources/portabilityLayer.php';
$tmpFile = sys_get_temp_dir() . "/xsrf.txt";
function fail($state)
{
header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET");
header("Access-Control-Max-Age: 0");
echo "FAILED: Issued a " . $_SERVER['REQUEST_METHOD'] . " request during state '" . $state . "'\n";
exit();
}
function setState($newState, $file)
{
file_put_contents($file, $newState);
}
function getState($file)
{
$state = NULL;
if (file_exists($file))
$state = file_get_contents($file);
return $state ? $state : "Uninitialized";
}
$state = getState($tmpFile);
if ($_SERVER['REQUEST_METHOD'] == "GET"
&& $_GET['state'] == "reset") {
if (file_exists($tmpFile)) unlink($tmpFile);
header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
header("Access-Control-Max-Age: 0");
echo "Server state reset.\n";
} else if ($state == "Uninitialized") {
if ($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
echo("Request Denied\n");
setState("Denied", $tmpFile);
} else {
fail($state);
}
} else if ($state == "Denied") {
if ($_SERVER['REQUEST_METHOD'] == "GET"
&& $_GET['state'] == "complete") {
unlink($tmpFile);
header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
header("Access-Control-Max-Age: 0");
echo "PASS: Request successfully blocked.\n";
} else {
setState("Deny Ignored", $tmpFile);
fail($state);
}
} else if ($state == "Deny Ignored") {
unlink($tmpFile);
fail($state);
} else {
if (file_exists($tmpFile)) unlink($tmpFile);
fail("Unknown");
}
?>
2010-04-02 Justin Schuh <jschuh@chromium.org>
Reviewed by Alexey Proskuryakov.
XHR allows arbitrary XSRF across domains
https://bugs.webkit.org/show_bug.cgi?id=36843
Added a one-line change to prevent bypassing the XDC check on
synchronous preflighted requests. Added layout tests to cover
variations of this problem.
Tests: http/tests/xmlhttprequest/access-control-preflight-async-header-denied.html
http/tests/xmlhttprequest/access-control-preflight-async-method-denied.html
http/tests/xmlhttprequest/access-control-preflight-sync-header-denied.html
http/tests/xmlhttprequest/access-control-preflight-sync-method-denied.html
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::preflightFailure):
2010-04-02 Nayan Kumar K <nayankk@gmail.com>
 
Reviewed by Eric Seidel.
......@@ -291,6 +291,7 @@ void DocumentThreadableLoader::preflightSuccess()
void DocumentThreadableLoader::preflightFailure()
{
m_actualRequest = 0; // Prevent didFinishLoading() from bypassing access check.
m_client->didFail(ResourceError());
}
......
Supports Markdown
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