编程语言
首页 > 编程语言> > php – 独特的表单令牌禁用用户的多任务处理

php – 独特的表单令牌禁用用户的多任务处理

作者:互联网

如果我想保护我的网站和用户免受Cross Site Forgery(CSRF)攻击,我可以生成一个唯一的令牌$token = md5(time()* rand);在每个有表单的页面上.令牌在隐藏的输入字段中提交echo’< input type =“hidden”name =“token”value =“'.$token.'”>‘;并同时存储在会话变量$_SESSION [‘token’] = $token;中.

我会检查是否在任何提交的表格中($_ POST [‘token’] == $_SESSION [‘token’])并相应地继续.

但是有些用户可能会多任务.这是我现在正在做的事情,而我发布这个.

在撰写我的帖子时,我打开了不同的窗口/标签,可能会研究信息或查看有关堆栈溢出的其他一些问题.堆栈溢出让我提交表单没有问题.

但是如果我在我的网站上这样做 – 这意味着在编写帖子/表单的同时浏览其他页面 – 每次我从我的网站上拉出一个不同的页面时,我的$token将被重新生成.在我正在处理的表单上创建隐藏的输入标记,并最终想要提交不正确的,因为它不再匹配$_SESSION [‘token’]变量,当我访问不同的页面时已经重新生成了…

任何好的想法如何防止这个问题,或者首先停止CSRF的任何更好的解决方案?

我希望允许我的用户执行多任务并希望受到CSRF的保护……

解决方法:

由于单个CSRF,我遇到的问题与你说的一样,除非他们提交了最新的页面,否则它会被替换,但是如果你使用数组w / session它应该解决你的问题.您也可以想要包含验证码,我建议使用Google的Recaptcha.

session_start();
function createToken(){
    $token = sha1(uniqid(mt_rand(), true));
    $_SESSION['Tokens']['Token'][] = $token;
    $_SESSION['Tokens']['Time'][] = time() + (10 * 60); #10 min limit
    #you can omit/change this if you want to not limit or extend time limit
    return $token;
}

function checkToken($token){
    clearTokens();
    foreach($_SESSION['Tokens']['Token'] as $key => $value){
        if($value === $token){
            return true;
        }
    }
    return false;
}

function clearTokens(){
    foreach($_SESSION['Tokens']['Time'] as $key => $value){
        if($value <= time()){
            unset($_SESSION['Tokens']['Token'][$key], $_SESSION['Tokens']['Time'][$key]);
            #remove last parameter if you aren't using token time limit
        }
    }
}

你的HTML:

<input type="hidden" name="token" value="<?php createToken(); ?>">

PHP令牌检查器

if(isset($_POST['token']) && checkToken($_POST['token'])){
    #valid token
}else{
    #create error message saying that they tried to repost data or session token expired
}

标签:csrf-protection,php,forms,csrf,token
来源: https://codeday.me/bug/20190825/1720119.html