我正在努力保护我在PHP / HTML / Javascript中创建的表单免受CSRF攻击。我有一个类做两件事 - 一个生成并返回随机令牌的函数,另一个函数检查令牌是否存在于当前会话中以及令牌是否相等。第一个我会遗漏,因为它只是生成一个令牌。
public static function checkToken($token) {
if(!empty($_SESSION['token']) && $token === $_SESSION['token'])) {
unset($_SESSION['token']);
return true;
}
return false;
}
在表单所在的主页上 - 我开始一个会话并检查我的提交按钮的名称是否等于其值(在提交时获得):
if($_POST['submit_app'] == "Submit" && $_POST['token']) {
if(Token::checkToken($_POST['token'])) {
echo 'Token OK';
} else {
die();
}
}
我故意改变了谷歌浏览器(F12)中的Web开发工具中的令牌,但表格似乎仍然进入我的处理页面(用PHP编写)。使用die();
不会阻止其他处理表单处理吗?如果令牌不匹配,如何停止提交数据?
我知道PHP是一种服务器端语言,所以我可能不得不做一些其他的事情来阻止提交,但是我想要一种方法可以在它处理表单上的数据之前杀死脚本,如果代币不一样。
答案 0 :(得分:0)
正如您所说,PHP是一个服务器端脚本,无法阻止提交表单。表单是在客户端提交的,所以防止这种情况的唯一方法是使用客户端脚本,如javascript。
通过在iframe中嵌入外部表单来完成CSRF攻击。你可以做什么服务器端是防止这种行为。您可以使用.htaccess
X-Frame-Options完成此操作。要防止CSRF攻击,您可以使用:
Header set X-Frame-Options SAMEORIGIN
只需将其添加到您的.htaccess
文件即可。 SAMEORIGIN
设置允许在同一网站的页面框架中提供页面。如果外部站点尝试在帧中加载页面,则请求将被拒绝。您也可以在这里使用DENY
选项,如果您从不打算在页面内使用页面,则应使用该选项。
请注意,这对旧浏览器不起作用。浏览器兼容性: