feat(mcp): tools/call 自请求分发、CSRF 内部标记豁免与调用审计

This commit is contained in:
augushong
2026-08-16 22:46:32 +08:00
parent c21bf9f240
commit 0d20fd7786
3 changed files with 175 additions and 11 deletions

View File

@@ -12,6 +12,22 @@ class CsrfMiddlewareBase
{
if (env('adminsystem.IS_CSRF', true)) {
if (!in_array($request->method(), ['GET', 'HEAD', 'OPTIONS'])) {
// MCP 内部分发豁免(唯一豁免通道,安全性论证):
// 1. mcp_internal 标记只能由服务端写入 login 缓存McpDispatch 生成的一次性
// creator token攻击者需先具备服务器内部写缓存能力才可伪造
// 2. 跨站表单/HTML 场景无法携带 Authorization 自定义头(浏览器表单不透传该头),
// 对该头的 CSRF 攻击模型本身不成立;
// 3. 豁免标记与 5 分钟一次性 token 同生命周期McpDispatch 调用结束即删
// try/finally缓存 TTL 到期自动失效,不残留长期豁免通道。
$authorization = $request->header('authorization', '');
$token = (strpos($authorization, ' ') !== false) ? trim(explode(' ', $authorization)[1]) : '';
if (!empty($token)) {
$cached = \think\facade\Cache::store('login')->get($token);
if (!empty($cached['mcp_internal'])) {
return $next($request); // MCP 内部分发标记,跳过 CSRF一次性短时 token
}
}
// 跨域校验
$refererUrl = $request->header('REFERER', null);
$refererInfo = parse_url($refererUrl);