我读过很多关于CSRF的文章,几乎所有的文章都有相同的解决方案,即隐藏令牌,所以我写了一个代码来防止CSRF,之后我尝试入侵我自己的页面,但它没有用,我想知道我的代码是否是CSRF防弹的,以及周围是否有任何东西。
我有四页包含表单,因此在每一页中我都会写以下内容:
if (isset($_POST['submit'])){
// Check for CSRF token
if ($_SESSION['token'] === $_POST['token']){
// write to db
}else{
// CSRF attack has been detected
die("CSRF :<br>1: $_SESSION[token] <br> 2: $_POST[token]");
}
}else{
// assign CSRF prevention token
$form_token = md5((rand(1,89412) * 256 / 4).$date.time());
$_SESSION['token'] = $form_token;
}
?>
<form action='' method='post'>
<input type='hidden' name='token' value='<?echo $form_token;?>'>
这种方法是否足以阻止攻击者在我的网站上使用 CSRF?
多谢。
我将向您展示我的CSRF预防代码:
配置.php
配置文件应使用require
或include
函数在每个页面中自动加载。
最佳做法是编写一个配置类(我只写下函数以简化我的代码)。
session_start();
if(empty($_SESSION['CSRF'])){
$_SESSION['CSRF'] = secureRandomToken();
}
后.php
这只是一个例子。在每个"帖子"页面中,您应该检查是否设置了CSRF令牌。请使用POST
方法提交您的表格!我还建议您查看Slim Framework或Laravel Lumen,它们提供了一个出色的路由系统,可让您非常轻松地仅在"post.php"页面上接受POST请求(它们还会自动添加每种形式的CSRF令牌)。
if (!empty($_POST['CSRF'])) {
if (!hash_equals($_SESSION['CSRF'], $_POST['CSRF'])) {
die('CSRF detected.');
}
}else{
die('CSRF detected.');
}
查看.php
现在,您只需在其中放置一个带有CSRF会话值的隐藏输入。
<input type="hidden" name="CSRF" value="<?= $_SESSION['CSRF'] ?>">
我希望这个快速的解释可以帮助你:)