CSRFトークンがSet-Cookieされていないと騒ぐな
Laravelなどのフレームワークを使っていると勘違いしがちですが、CSRFトークンは基本的にhidden型のinput要素に埋め込まれるため、Cookieにトークンはありません。
この場合のCSRF対策としてCookieに必要なのはセッションIDのみです。POSTされたトークンとセッション変数のトークンを検証すれば正規のリクエストか分かります。
ただし、Cookieにトークンが存在するケースもあります。例えばLaravelだとXSRF-TOKENというCookieがデフォルトでセットされます。
これはAxiosなどのHTTPクライアントで使用されるCSRFトークンをCookieにセットしているだけで、input要素のトークンも埋め込まれています。通常使われるのはそちらのトークンです。
CSRF対策がされたフォームの例
以下はCSRF対策済みのフォームの簡易的なコードです。
このように、CSRFトークンがフォームに埋め込まれた状態のレスポンスをサーバは返します。
CookieにCSRFトークンを格納することはあまりありません。
<?php
session_start();
$token = bin2hex(openssl_random_pseudo_bytes(24));
$_SESSION['token'] = $token;
?>
<body>
<form action="post.php" method="POST">
<textarea name="comment"></textarea>
<input type="hidden" name="token" value="<?= htmlspecialchars($token, ENT_COMPAT, 'UTF-8'); ?>">
<input type="submit" value="login">
</form>
</body>
CSRF対策についての詳細が知りたい方は以下の記事を参考にしてください。
CSRFの基本的な対策とLaravelにおけるCSRF対策の実装について