CSRF 是由攻击者执行的恶意活动,攻击者代表经过身份验证的用户执行操作,对 Web 安全有害。 幸运的是,Laravel 提供了防止此类漏洞的工具。
CSRF 攻击劫持用户会话。 他们通过在用户不知情的情况下通过隐藏的表单标签或恶意 URL(图像或链接)诱骗用户提交请求来做到这一点。
这种攻击会导致用户会话状态发生变化、数据泄露,有时黑客还可以操纵应用程序中的最终用户数据。
上图说明了网络安全遭到破坏的场景。 受害者通过单击链接(已收到)发送请求,将请求发送到网站服务器,这将产生黑客所需的效果,黑客将获得对访问和操纵网站服务器有用的信息。
为了提高 安全 在你的应用程序的 web 中,在每个用户会话中,Laravel 生成安全令牌,它使用它来确保经过身份验证的用户是请求应用程序的用户。
由于每次重新生成用户会话时此令牌都会更改,因此攻击者无法访问它。
每当有更改服务器端(后端)用户信息的请求时,例如 POST
, PUT
, PATCH
e DELETE
,您必须包含指令 @csrf
在申请表中 blade
HTML。 这 @csrf
因此它是一个指令 Blade
用于生成由应用程序验证的隐藏令牌。
该指令 Blade
是 Laravel 模板引擎中使用的语法,称为 刀片 . 创建文件 blade
你必须给它一个名字——在我们的案例中——然后是刀片的扩展。 这意味着该文件将具有名称 form.blade.php
.
该文件被使用 blade
在网页上为用户呈现视图。有几个预先指令defi您可以使用 nite 或 Blade 速记语法。 例如, @if
检查条件是否满足, @empty
检查记录是否不为空, @auth
检查用户是否通过身份验证等。
但是让我们回到指令 @csrf
. 以下是您如何使用它:
<form method="POST" action="{{route('pay')}}">
@csrf
</form>
以前版本的 Laravel 有不同的设置:它们都工作并且做同样的事情。
<form method="POST" action="{{route('pay')}}">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
当正在提交的表单请求中缺少 CSRF 令牌或者它看起来无效时,Laravel 会抛出一个“页面已过期”错误消息和 419 状态代码。
中间件 VerifyCsrfToken
在 Laravel 应用程序中处理 CSRF 验证。 这 middleware
注册于 Kernel.php
并且位于目录中 app/Http/Middleware
. 这意味着 middleware
它是为网络中的请求触发的,与 API 无关。
protected $middlewareGroups = [
'web' => [
.
.
.
.
.
\App\Http\Middleware\VerifyCsrfToken::class,
],
];
VerifyCsrfToken 中间件扩展类 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
,即 CSRF 验证是 defi晚上在班级里。
让我们更深入地了解 Laravel 如何处理 CSRF 验证。
在类里面,我们有函数 tokensMatch
.
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request);
return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
}
在代码中确定会话和输入的 CSRF 令牌是否匹配。
该函数做了两件事:
$this->getTokenFromRequest
来自通过隐藏字段或请求标头附加的传入请求的令牌。 令牌被解密,然后返回到令牌变量。protected function getTokenFromRequest($request)
{
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
try {
$token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
} catch (DecryptException $e) {
$token = '';
}
}
return $token;
}
在代码中,它从标头获取令牌
2.将请求令牌和会话都转换为字符串,然后使用 hash_equals
内置 PHP 以比较两个字符串是否相等。 这个操作的结果总是 布尔(真)或(假) .
Ercole Palmeri