快速CSRF令牌

时间:2015-03-08 07:58:36

标签: php csrf

所以我在上一个关于生成CSRF令牌的线程中找到了一个教程......现在我应该如何实现它呢?

我已经尝试过为每个表单请求生成一个新令牌(但是尝试执行多个表单请求使其无效以便从列表中删除)并且从读取其他线程为每个用户登录创建一个会话令牌是要走的路

那么最好的方法是什么?我应该在用户登录时这样做,它只会自动分配

   $_SESSION['CSRFToken']

并指定散列/ 256位值?然后将该会话令牌分配给每个表单。我想我只是不明白CSRF是如何工作的,以及如何真正做些什么。基本上听起来我应该让每个用户登录都有一个名为安全令牌的会话,它出现在每个表单中。

感谢您的帮助!

2 个答案:

答案 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。