0

所以我有一个 laravel 5 项目,我想用 siege 工具对我正在使用的测试服务器进行基准测试。

不幸的是,我意识到您无法登录,因为 CSRF 通常是从提交表单中收到的。围攻中没有表格,所以这个令牌无法发送。

我可以通过几种方式解决这个问题,但我正在寻找可以留在源代码控制中并且不会对安全性产生负面影响的东西。什么是让围攻与 Laravel 一起工作的好方法,而无需大量维护或只是懒惰并禁用 CSRF?

4

2 回答 2

1

两件事情:

  1. 您可以设置围攻以登录您的站点。有关更多信息,请参阅此 ServerFault 帖子,但这只会测试您的登录表单。
  2. 您可以使用相同的方法发送_token任何请求的参数

显然,这方面的文档可以在代码的注释中找到,而不是在官方手册中。

你剩下的问题是_token变量传递什么值。显然,假值正是 CSRF 应该防止的那种东西。我认为最简单的方法是修改app/Http/Middleware/VerifyCsrfToken.php以添加一个特殊条件,该条件将与预设值“匹配”。

我要做的第一件事是在我的.env文件中创建一个包含我的面部 CSRF 令牌的变量,例如

FAKE_CSRF_TOKEN=dd0dda7d4b5e92fafd9e5bebfabd7709

然后在App\Http\Middleware\VerifyCsrfToken(即我上面提到的文件)中,您将覆盖该tokensMatch($request)函数。您可能会执行以下操作:

protected function tokensMatch($request)
{
    $parent = parent::tokensMatch($request);
    $token = $request->input('_token');
    return $parent || $token == env('FAKE_CSRF_TOKEN');
}

然后在您的测试中,始终将您的假 CSRF 令牌值传递为_token. 当然,

这段代码永远不应该在生产服务器上运行!

如果是我,我可能会创建一个特殊.env.siege文件并设置APP_ENV=siege在我的测试或登台服务器上。然后我会重写上面的tokensMatch()函数来做这样的事情:

protected function tokensMatch($request)
{
    $parent = parent::tokensMatch($request);
    if ('siege' === env('APP_ENV')) {
        $token = $request->input('_token');
        return $parent || $token == env('FAKE_CSRF_TOKEN');
    }
    return $parent;
}

这样,即使这个经过修改的中间件以某种方式进入了您的生产服务器,您也可以获得一些额外的保护来抵御虚假的 CSRF 攻击。最终结果是,您几乎可以像在生产环境中一样对服务器进行压力测试,而无需禁用 CSRF。

说了这么多,我不知道资源密集型 CSRF 检查实际上是如何进行的。为您的压力测试关闭 CSRF 可能会更简单,而不是进行我在此处建议的更改。

于 2015-11-03T21:58:32.387 回答
0

所以上面的答案就差不多了,但是它有以下缺陷:

  • 它需要自己的配置类型。不行;我们只是希望生产能够免疫。其他任何东西都应该在适当的位置进行压力测试。
  • 它不包括 FAKE_CSRF_TOKEN 不是由草率的开发人员定义的
  • 它必须能够提交到主树!Git是常用的部署机制,尽量少在VCS之外

所以我这样定义函数:

protected function tokensMatch($request)
{
    $parent = parent::tokensMatch($request);

    //if it isn't an actual token match, and we aren't on production
    if (! $parent && 'production' !== env('APP_ENV')) {
        //then get the token
        $token = $request->input('_token');
        $fake = env('FAKE_CSRF_TOKEN');

        //and test it versus our fake
        //it must actually be defined to work (no blanks)
        //generate an actual random string for security!
        if(strlen($fake) && $token === $fake)
            return true;
    }

    //otherwise, just return what we normally would
    return $parent;
}
于 2015-11-04T21:31:17.417 回答