You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CSRF测试中POST与Cookie令牌值不匹配问题求助

问题原因分析

1. Cookie生效时机偏差

第一次访问页面时,PHP通过setcookie()设置的Cookie是随HTTP响应头发送给浏览器的,浏览器只有接收完响应才会存储这个Cookie。但此时页面中<?php echo $_COOKIE['csrfToken']; ?>读取的是当前请求里浏览器发送的Cookie——第一次访问时浏览器还没收到新设置的Cookie,所以这里输出为空,导致表单隐藏域的csrfToken值是空的。

2. 提交操作的页面刷新干扰

提交按钮绑定的onclick="refreshPage()"会触发页面跳转,这会直接中断表单的POST提交流程:要么POST请求根本没发送成功,要么发送的同时页面已经刷新,而刷新后的页面又重新生成了新的CSRF令牌并覆盖Cookie,最终导致你看到的TOKEN2是新令牌,TOKEN是空或旧令牌,二者自然不一致。

3. 令牌生成逻辑错误

当前代码每次加载页面都会生成新令牌并覆盖Cookie,正确逻辑应该是仅当Cookie中没有令牌时才生成新的,否则复用已有令牌,这样表单和Cookie中的令牌才能保持一致。

修复后的代码示例
<!doctype html> 
<meta charset="utf-8"> 
<title> T CSRF_TEST.php </title>
<style> html * { font-size:1.75rem; font-family:monospace; } </style>

<?php
// 修正逻辑:仅在Cookie无令牌时生成新令牌
if (!isset($_COOKIE['csrfToken'])) {
    $csrfToken = bin2hex(random_bytes(32));
    setcookie("csrfToken", $csrfToken, time() + 3600);
} else {
    $csrfToken = $_COOKIE['csrfToken'];
}
?>

<form action="CSRF_TEST.php" method="POST">
<!-- 直接使用PHP中处理好的令牌,绕过Cookie生效时机问题 -->
<input type="hidden" name="csrfToken" value="<?php echo $csrfToken; ?>">
<!-- 移除手动刷新,表单提交后会自动跳转处理请求 -->
<input type="submit" value="Submit">
</form>

<?php
echo "<br>";

// 增加空值判断,避免未提交时出现Undefined索引错误
$TOKEN = $_POST["csrfToken"] ?? '';
echo "<br>TOKEN= " . $TOKEN;

$TOKEN2 = $_COOKIE['csrfToken'] ?? '';
echo "<br>TOKEN2= " . $TOKEN2;

// 验证前先确保两个令牌都存在
if (!empty($TOKEN) && !empty($TOKEN2) && $TOKEN === $TOKEN2) {
    echo "<br>APPROVED REQUEST";
} else {
    echo "<br>Reject the request";
}
?>
关键修复点说明
  • 令牌生成逻辑优化:仅在Cookie无令牌时生成新值,避免每次加载页面都覆盖原有令牌。
  • 表单令牌赋值优化:直接使用PHP中生成/获取的$csrfToken填充表单,绕过Cookie生效时机的问题。
  • 移除不必要的页面刷新:表单提交后会自动跳转到目标页面处理请求,无需手动刷新,避免中断提交流程。
  • 增加空值判断:验证前先检查POST和Cookie中的令牌是否存在,避免未提交时出现报错。

内容的提问来源于stack exchange,提问作者Rinaldo Rasa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:10:56