我发送跨站点伪造的jquery字符串令牌,但在下一页我生成一个新的令牌,然后他们的令牌将永远不匹配


I am sending Cross site forgery tokens over jquery strings, but on the next page I generate a new token and then their tokens will never match

好的,我将它们的令牌存储在一个会话中:

Session::get('token', 'randomtokenstringhere');
每个表单

,不管是成功与否我产生一个新的令牌,并更新他们的会话令牌,现在说例如user 1更新个人资料页面,我序列化形式,令牌在页面加载回声令牌变量)提交表单,ajax运行,完成或有一个错误,我的系统生成一个新的令牌,在编辑个人资料页面,但是现在他们仍然使用旧的令牌,所以现在他们的令牌永远不会匹配。

我如何修复这个额外的安全性?

这是我的ajax的一个例子:

<!-- accept, reject, add and cancel friend requests -->
$('.add_friend').click(function(event) { // bind function to submit event of form
    event.preventDefault();
    $.ajax({
        url: $(this).attr('href'),
        success: function(responseText) {
            if($(event.target).text() == 'Add as friend'){
                $(event.target).attr("href", "<?php echo Config::get('URL'); ?>friends/cancel_request/" + $(event.target).attr('id') + "/<?php echo System::escape(Session::get('token')); ?>");
                $(event.target).text('Cancel Request');
                $(event.target).removeClass("add_friend btn btn-success").addClass("cancel_request btn btn-info");                  
            }else{
                $(event.target).attr("href", "<?php echo Config::get('URL'); ?>friends/addfriend/" + $(event.target).attr('id') + "/<?php echo System::escape(Session::get('token'));?>");
                $(event.target).text('Add as friend');  
                $(event.target).removeClass("cancel_request btn btn-info").addClass("add_friend btn btn-success");                  
            }
        }
    });
    return false;
});
<!-- End Like a status -->

当然会运行以下链接:

<a class="add_friend btn btn-success" id="<?php echo System::escape($likes->timeline_likes_id); ?>" href="<?php echo Config::get('URL'); ?>friends/addfriend/<?php echo System::escape($likes->user_id).'/'.System::escape(Session::get('token')); ?>"><?php echo System::translate("Add as friend"); ?></a>

他们的令牌是:System::escape(Session::get('token')); ?>只会加载页面刷新默认我使用ajax的原因

您需要实现nonce !摘自维基百科文章:

nonce是在密码学中只使用一次的任意数字沟通,在一个现代世界的精神。它们通常是随机的伪随机数字。许多nonce还包含时间戳以确保准确的时效性……为了确保nonce只被使用一次,它应该是时变的(在其值),或者生成足够的随机位以确保a重复先前事件的概率微不足道生成的值。一些作者将伪随机性定义为不可预测性)作为nonce的要求。

无论如何,任何实际实现都需要至少2个函数。第一个是类似createNonce()的东西第二个是类似verifyNonce()的东西。如果你正在寻找一个库来为你做这件事,我过去用过OpenID。

有很多有效的方法可以做到这一点,并且编写自己的实现相当简单。基本概念是创建一个可以复制数据的字符串。然后散列该数据并将其放入表单中的字段中。然后,当您获得表单数据时,您可以重新创建您的散列,并将其与表单发送的散列进行比较(类似于验证密码的方式)。你需要确保你的哈希包含有规律变化的数据(例如microtime()),这样你的随机数是唯一的。对于用户登录的系统,我经常使用该用户的一些东西(例如,他们的密码哈希的子字符串),以便每个用户获得一个唯一的nonce,即使它们都是在同一微秒内生成的。

要更新javascript中的值,你需要稍微修改一下你的js。

像这样的东西应该会让你走上正确的轨道

<!-- accept, reject, add and cancel friend requests -->
$('.add_friend').click(function(event) { // bind function to submit event of form
    event.preventDefault();
    var token = <?php echo System::escape(Session::get('token'));?>;
    $.ajax({
        url: $(this).attr('href'),
        success: function(responseText) {
            if($(event.target).text() == 'Add as friend'){
                $(event.target).attr("href", "<?php echo Config::get('URL'); ?>friends/cancel_request/" + $(event.target).attr('id') + "/" + token);
                $(event.target).text('Cancel Request');
                $(event.target).removeClass("add_friend btn btn-success").addClass("cancel_request btn btn-info");                  
            }else{
                $(event.target).attr("href", "<?php echo Config::get('URL'); ?>friends/addfriend/" + $(event.target).attr('id') + "/" + token);
                $(event.target).text('Add as friend');  
                $(event.target).removeClass("cancel_request btn btn-info").addClass("add_friend btn btn-success");                  
            }
            token = responseText;
        }
    });
    return false;
});
<!-- End Like a status -->

现在您所要做的就是修改$(this).attr('href')的表单处理程序以回显新的会话令牌。JS会将令牌值设置为新的令牌,并在随后的请求中使用。

这样做是把你的令牌放在一个变量中,这个变量可以在每次调用后更新,这样你就可以在请求成功后更改它。