1

我想延长我的 CSRF 令牌到期时间。我知道laravel-caffeine,但如果页面空闲太久,令牌仍然过期。(例如 24 小时以上)

所以我想出了一个想法,首先使用 ajax GET 方法检索最新的 csrf 令牌,然后使用这个刷新的令牌提交表单。

但我不确定是否存在一些安全问题。例如,假设可以在http://example.com/get_csrf 获取最新的 csrf 令牌,并且攻击者也可以访问此 URL。我想知道对手是否可以利用它并破坏 csrf 保护?

4

3 回答 3

4

是的,您的担忧是正确的。该令牌用于防止其他网站通过受害者的会话向您的网站创建请求。如果可以从攻击网站完成,则通过 ajax 使令牌可请求可能会产生问题。

于 2019-08-09T08:43:14.800 回答
2

您可以通过以下方式保护/get_csrf路线:

  1. 提供表单时保存csrf_token()服务器端并将其保存在用户表的列中:
//in your controller

public function showMyForm(){
    $user=auth()->user();
    $user->last_csrf=csrf_token(); // save the csrf token
    $user->save(); //persist to database

    return view('myform');
}
  1. 让您的 get_csrf 路由验证旧令牌并返回新令牌:
//in your other controller (Route::get('/get_csrf','Controller@getCSRF');)

public function getCSRF(Request $request){
    $user=auth()->user();
    $old_user_token=$user->last_csrf;
    $old_client_token=$request->current_token;
    if ($old_client_token && $old_user_token==$old_client_token){

        // it's a match, update the token in the users table and send the new one
        $user->last_csrf=csrf_token();
        $user->save();
        return csrf_token();
    }

    //no match, tell the client he is unauthorized to get the new csrf token
    abort(401);
}
  1. 将页面的当前 csrf 作为有效负载的 ajax GET:(在此处使用 jquery,但您不需要)
$.ajax({
    url:'/get_csrf',
    method:'POST',
    dataType:"json",
    headers:{
        // have the server treat the request as GET
        'X-HTTP-Method-Override': 'GET' 
    },
    data:{
        // send the page's current csrf in the payload
        current_token:document.querySelector('meta[name="csrf-token"]').getAttribute('content') 
    },
    success(data){

        // this is whatever the server sent back as the current csrf for this session
        new_csrf=data; 

        // update the page's csrf
        document.querySelector('meta[name="csrf-token"]').setAttribute('content',new_csrf);

        //update any _token fields
        document.querySelectorAll('input[name="_token"]').forEach(function(csrf_field){

            csrf_field.setAttribute('value',new_csrf);

        });


    },
    error(response){
        // error handling. maybe console.log(response) here to see what happened?
    }
});
  1. 像往常一样提交您的表格。
于 2019-08-09T09:55:01.650 回答
0

如果攻击是通过 iframe 进行的,则 js 代码可以截取受害者 iframe 的屏幕截图,而不是解析 csrf 令牌,并且可以用于另一个请求(理论上)。

于 2021-09-19T23:48:53.177 回答