所以我在上一个关于生成CSRF令牌的线程中找到了一个教程......现在我应该如何实现它呢?
我已经尝试过为每个表单请求生成一个新令牌(但是尝试执行多个表单请求使其无效以便从列表中删除)并且从读取其他线程为每个用户登录创建一个会话令牌是要走的路
那么最好的方法是什么?我应该在用户登录时这样做,它只会自动分配
$_SESSION['CSRFToken']
并指定散列/ 256位值?然后将该会话令牌分配给每个表单。我想我只是不明白CSRF是如何工作的,以及如何真正做些什么。基本上听起来我应该让每个用户登录都有一个名为安全令牌的会话,它出现在每个表单中。
感谢您的帮助!
答案 0 :(得分:2)
你有基本的想法。从本质上讲,CSRF令牌的目的是确保页面不能包含在应用程序中触发某些内容的iFrame。作为一个基本的例子:
<iframe src="http://example/delete.php?accept=true"></iframe>
通常,每个会话生成一个CSRF令牌是可以的,但您可能希望为每个请求生成唯一令牌,并检查它。这样做可以提高应用程序的安全性,但不需要。
可以在此处找到快速参考:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
<强>更新强>:
你不会通过$ _REQUEST本身来做,你可以在表格生成页面上创建这样的东西
$form_session_key = bin2hex(random_bytes(32)); // For more options see http://stackoverflow.com/a/31683058/453273
!isset($_SESSION['CSRF_CONTENTS']) ? $_SESSION['CSRF_CONTENTS'] = array() : 0;
$_SESSION['CSRF_CONTENTS'][] = $form_session_key;
//SNIP
<form action="process.php" method="POST">
<input type="text" style="display: none" id="CSRF" contents="<?php echo $form_session_key; ?>" />
</form>
在您的处理页面上
!in_array($_POST['CSRF'], $_SESSION['CSRF_CONTENTS']) ? exit : 0;
如果CSRF密钥不在页面加载时生成的CSRF_CONTENTS数组中,则退出上述代码段。
答案 1 :(得分:0)
首次登录会话时,将使用CSRFToken生成会话,并且此令牌将分配给每个页面表单,直到注销。 因此,对于一个会话,生成一个CSRFToken来验证表单,当然它是一个哈希值。
在表单提交期间,如果我们的cookie或会话被劫持,则不能提交任何不可预测的数据,因为每个表单提交都会检查CSRFToken。