如果令牌不匹配,则阻止表单提交?

时间:2014-09-22 15:16:33

标签: php html forms csrf

我正在努力保护我在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是一种服务器端语言,所以我可能不得不做一些其他的事情来阻止提交,但是我想要一种方法可以在它处理表单上的数据之前杀死脚本,如果代币不一样。

1 个答案:

答案 0 :(得分:0)

正如您所说,PHP是一个服务器端脚本,无法阻止提交表单。表单是在客户端提交的,所以防止这种情况的唯一方法是使用客户端脚本,如javascript。

通过在iframe中嵌入外部表单来完成CSRF攻击。你可以做什么服务器端是防止这种行为。您可以使用.htaccess X-​​Frame-Options完成此操作。要防止CSRF攻击,您可以使用:

Header set X-Frame-Options SAMEORIGIN

只需将其添加到您的.htaccess文件即可。 SAMEORIGIN设置允许在同一网站的页面框架中提供页面。如果外部站点尝试在帧中加载页面,则请求将被拒绝。您也可以在这里使用DENY选项,如果您从不打算在页面内使用页面,则应使用该选项。

请注意,这对旧浏览器不起作用。浏览器兼容性:

  • Internet Explorer 8 +
  • Opera 10.50 +
  • Safari 4 +
  • Chrome 4.1.249.1042 +
  • Firefox 3.6.9+(或更早版的NoScript)