当使用 cookie 进行会话管理的 Web 应用程序无法验证 HTTP POST 请求的来源时,通常会出现 CSRF(跨站点请求伪造)漏洞。
当 Web 应用程序通过使用 GET 方法进行更改而滥用 GET 方法时,也会发生这种情况。这两种情况都允许恶意网站代表登录用户执行不需要的操作。
按着这些次序。
在开始之前,了解 SOP(Same Origin Policy)是很有帮助的,它是 Web 浏览器安全模型的核心和灵魂。这是一个或多或少说的规则:
GET
来源发送、、、POST
和请求。此外,该请求将包括该来源的用户 cookie(包括会话 ID)。HEAD
OPTIONS
anotherWindow.location.replace("https://www.evil.com"
)。例如,这个网站的来源是在https://www.appsecmonkey.com/
哪里,主机在哪里,并且没有指定端口(这是隐含的,因为协议)。protocol
https
www.appsecmonkey.com443https
让我们假设用户可以像这样登录 AppSec Monkey 并更新他们的电子邮件地址:
POST /user/update-email/ HTTP/1.1
Host: www.appsecmonkey.com
Cookie: SessionId=ABC123
...
[email protected]
后端代码可能看起来像这样(至少如果你使用 Django):
def update_email(request):
new_email = request.POST['new_email']
set_new_email(request.user, new_email)
现在假设有一个evil.example.com
带有以下 HTML 表单和自动提交脚本的邪恶网站:
当当前登录的用户www.appsecmonkey.com
进入恶意网站时,将代表用户自动提交 HTML 表单,并立即将以下 HTTP POST 请求发送到www.appsecmonkey.com
:
POST /user/update-email/ HTTP/1.1
Host: www.appsecmonkey.com
Cookie: SessionId=ABC123
...
[email protected]
Bob 的电子邮件地址更改为[email protected]
.
防止这些攻击的常用方法是使用称为 CSRF 令牌的东西。它可以让您在 HTML 表单中添加一个隐藏的值,攻击者无法猜到。
当另一个网站喜欢evil.example.com
尝试提交表单时,网络服务器会拒绝 POST 请求,因为它不包含用户的 CSRF 令牌。
所有现代 Web 应用程序框架(Spring、Express、Symfony、Django、ASP.Net MVC等)。物有所值有这样的 CSRF 保护机制,所以不要创建自己的.
这是你的第一道防线。
它也是一个漏洞,通常可以通过某种方式利用,如果恶意网站可以在不知不觉中使用他们的帐户登录您的用户。
为防止这种情况,请确保在登录表单中也使用 CSRF 令牌。
您应该将令牌绑定到预身份验证会话(当用户进行身份验证并为用户提供新的会话 ID 时,您应该将其丢弃,但这是另一回事)。
或者,如果您使用 OAuth/OIDC,请确保您state
正确验证了参数(有关详细信息,请参见此处)。
在这两种情况下,现代应用程序框架都应该能够毫不费力地处理它。
CSRF-token 机制倾向于只保护 POST 请求。因此,如果您接受 GET 请求,例如https://www.appsecmonkey.com/user/[email protected]
,无论您可能使用任何 CSRF 保护,您通常都容易受到攻击。
确保您不使用除 POST/PUT/PATCH/DELETE 之外的任何东西进行更改。
现代平台倾向于明确动词,但有时您必须小心遗留框架。
现在的浏览器支持一个很酷的特性,叫做SameSite cookie。当您使用 设置 cookie 时SameSite=Lax
,浏览器不会将其包含在跨站点 POST 请求中。
Set-Cookie: SessionId=123; ...other options... SameSite=Lax
就是这样,简单而有效。但是不要仅仅依靠这个特性来保证你的应用程序的安全。使用 CSRF 令牌作为您的主要防御,并应用 SameSite cookie 作为额外的保护层。
您还可以在SameSite=Strict
模式下设置 cookie。在这种情况下,GET 请求也将受到保护。但是,如果您遵循上述注意 HTTP 动词的规则,这对于 CSRF 保护来说不是必需的。而且它会在某种程度上破坏功能,因为指向应用程序的链接将不再按预期工作(在打开选项卡/窗口时将不再登录用户)。
使用该Strict
变体的好处是可以防止某些 XSS(跨站点脚本)攻击,因此您可能至少要考虑一下。
CSRF 是一个影响使用 cookie 进行会话管理的应用程序的漏洞。避免它们的一种方法是使用其他东西,例如 JavaScript 会话令牌。但这种方法也有缺点。例如,XSS 攻击可以访问令牌。相比之下,Web 应用程序可以使用该HttpOnly
属性保护 cookie 免受 JavaScript 代码的影响。
CSRF 攻击可能很危险。幸运的是,只要您使用支持 CSRF 令牌并明确 HTTP 动词的体面、现代的应用程序平台,它们也很容易避免。SameSite cookie 为您的应用程序提供了出色的附加安全层,但不应仅依赖于安全性。