Php 发布旧令牌的反CSRF实现

Php 发布旧令牌的反CSRF实现,php,http-post,csrf,Php,Http Post,Csrf,我在登录表单上实现CSRF保护时遇到一些问题。以下是登录的一般流程: 这包括在登录页面的顶部: // Create CSRF token $token = $auth->random(64); // 64 psuedorandom characters from /dev/urandom $_SESSION['token'] = $token; 登入表格: <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method

我在登录表单上实现CSRF保护时遇到一些问题。以下是登录的一般流程:

这包括在登录页面的顶部:

// Create CSRF token
$token = $auth->random(64); // 64 psuedorandom characters from /dev/urandom
$_SESSION['token'] = $token;
登入表格:

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<input type="submit" name="login" value="Login" />
</form>
当$auth->login收到输入时,问题开始出现。$\u会话令牌等于生成的令牌,但$\u POST令牌等于上次提交期间的$\u会话令牌

示例var_从$auth->login转储:

首先提交变量转储:

$_SESSION Array
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79

$_POST Array
[username] => 
[password] => 
[token] => 2200bb8663f19d66639a7f4791ddb53c9d510802d0ed76c42ac8b3f6d9e1589a
[login] => Login
$_SESSION Array
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce

$_POST Array
[username] => 
[password] => 
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79
[login] => Login
$_SESSION Array
[token] => 8be7ecbdae6274d1ba5ce9e8ace0af7c76e3e7d181c507d3da9b8c35652865cc

$_POST Array
[username] => 
[password] => 
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce
[login] => Login
第二次提交变量转储:

$_SESSION Array
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79

$_POST Array
[username] => 
[password] => 
[token] => 2200bb8663f19d66639a7f4791ddb53c9d510802d0ed76c42ac8b3f6d9e1589a
[login] => Login
$_SESSION Array
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce

$_POST Array
[username] => 
[password] => 
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79
[login] => Login
$_SESSION Array
[token] => 8be7ecbdae6274d1ba5ce9e8ace0af7c76e3e7d181c507d3da9b8c35652865cc

$_POST Array
[username] => 
[password] => 
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce
[login] => Login
第三次提交变量转储:

$_SESSION Array
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79

$_POST Array
[username] => 
[password] => 
[token] => 2200bb8663f19d66639a7f4791ddb53c9d510802d0ed76c42ac8b3f6d9e1589a
[login] => Login
$_SESSION Array
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce

$_POST Array
[username] => 
[password] => 
[token] => 00a28586a1a89b30149ef130ca6f3c01a25435ad1b0ad1a19326205c75b80d79
[login] => Login
$_SESSION Array
[token] => 8be7ecbdae6274d1ba5ce9e8ace0af7c76e3e7d181c507d3da9b8c35652865cc

$_POST Array
[username] => 
[password] => 
[token] => e093e312b379d766d46083d616fa8655f1565dc19ed6b1f73108546cb5f43fce
[login] => Login
如果您仔细观察,您会发现$\u POST标记只是向下移动——成为上次提交时的$\u会话

这让我感到困惑,因为
$token
$\u SESSION['token']
只在页面顶部设置了一次——当用户单击submit时,它们应该没有什么不同

总之,$\u会话包含当前生成的令牌,$\u POST包含以前生成的令牌


有什么想法吗?谢谢大家!

问题在于会话令牌在登录处理代码之前被更改,您需要将令牌生成位移动到登录处理代码之后。

问题似乎就在这里:
我收回它!解决方案是将登录处理代码放在页面顶部,将令牌生成代码放在页面下方,最后将表单放在页面底部。最初,您的解决方案不起作用,因为处理程序仍在表单下方。认可的!很高兴它成功了,我很难回答这个问题,因为我在iPad上。否则会提供更多信息。