所以我有一个 laravel 5 项目,我想用 siege 工具对我正在使用的测试服务器进行基准测试。
不幸的是,我意识到您无法登录,因为 CSRF 通常是从提交表单中收到的。围攻中没有表格,所以这个令牌无法发送。
我可以通过几种方式解决这个问题,但我正在寻找可以留在源代码控制中并且不会对安全性产生负面影响的东西。什么是让围攻与 Laravel 一起工作的好方法,而无需大量维护或只是懒惰并禁用 CSRF?
所以我有一个 laravel 5 项目,我想用 siege 工具对我正在使用的测试服务器进行基准测试。
不幸的是,我意识到您无法登录,因为 CSRF 通常是从提交表单中收到的。围攻中没有表格,所以这个令牌无法发送。
我可以通过几种方式解决这个问题,但我正在寻找可以留在源代码控制中并且不会对安全性产生负面影响的东西。什么是让围攻与 Laravel 一起工作的好方法,而无需大量维护或只是懒惰并禁用 CSRF?
两件事情:
_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 可能会更简单,而不是进行我在此处建议的更改。
所以上面的答案就差不多了,但是它有以下缺陷:
所以我这样定义函数:
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;
}