如何保护 Blazor Server 免受跨域攻击?

How to secure Blazor Server against cross-origin attacks?

我想确保 Blazor Server 应用程序能够抵御跨域攻击,特别是针对 Blazor Server 使用的 SignalR hub。据我所知,有问题的应用程序不需要启用 any 跨源连接。

Microsoft 有一份 Blazor Server 威胁缓解文档,其中说明需要跨域保护(参见此处:Threat Mitigation)。该文档建议“打开恶意 WebSocket 也是可能的”并且

  • Blazor Server apps can be accessed cross-origin unless additional measures are taken to prevent it. To disable cross-origin access, either disable CORS in the endpoint by adding the CORS middleware to the pipeline and adding the DisableCorsAttribute to the Blazor endpoint metadata or limit the set of allowed origins by configuring SignalR for cross-origin resource sharing.
  • If CORS is enabled, extra steps might be required to protect the app depending on the CORS configuration. If CORS is globally enabled, CORS can be disabled for the Blazor Server hub by adding the DisableCorsAttribute metadata to the endpoint metadata after calling MapBlazorHub on the endpoint route builder.

如果我理解正确,我需要“通过将 CORS 中间件添加到管道并将 DisableCorsAttribute 添加到 Blazor 端点元数据来禁用端点中的 CORS”,但到目前为止我一直无法弄清楚这该怎么做。 [编辑:我认为我的回答涵盖了问题的这一部分。]

以上文章还引用了另一篇关于 SignalR 安全性的文章(参见此处:Security considerations in ASP.NET Core SignalR) which says that "The protections provided by CORS don't apply to WebSockets. For origin restriction on WebSockets, read WebSockets origin restriction"。

关于 WebSockets 源限制的文章描述了如何为 WebSockets 配置跨源保护,但是这在配置 Blazor Server 使用的 WebSockets 的上下文中没有解释,我还没有弄清楚如何做到这一点。

如何确保我的 Blazor Server 应用程序是安全的,以防止通过其 WebSocket 或任何其他相关连接机制对 SignalR 集线器的跨源请求?

我想我已经找到了解决方案。我对它并不完全满意,但它似乎可以完成这项工作。此解决方案分为三个部分:

  1. 按照文档中的建议将 DisableCorsAttribute 应用于 Blazor 端点。
  2. 阻止对 Blazor WebSockets 端点的跨源请求。
  3. 向 Blazor 端点申请授权(严格来说这与跨源请求无关,但我认为这里值得一提)。

1。 DisableCorsAttribute

Startup.ConfigureServices() 中添加 services.AddCors(); - 我认为我不需要在此处添加策略,因为我实际上不想为我自己站点以外的任何来源启用 cors。

Startup.Configure()中添加app.UseCors();app.UseRouting();之后但在app.UseEndpoints();

之前的某处

使用 WithMetadata()DisableCorsAttribute 添加到 Blazor 端点元数据:

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub().WithMetadata(new DisableCorsAttribute());
    endpoints.MapFallbackToPage("/_Host");
});

2。阻止对 Blazor WebSockets 端点的跨源请求

CORS 策略不适用于 websockets(因此所有的麻烦)。这个解决方案似乎有点 hacky,但它似乎有效,我愿意接受改进建议或更好的解决方案。我在 Startup.Configure() 方法的顶部有这个,这样对 Blazor WebSockets 端点的跨源请求将被有效地忽略,而不是将错误代码返回给潜在的攻击者。

app.Use(async (context, next) =>
{
    if (context.Request.Path.Value == "/_blazor")
    {
        if (context.Request.Headers.TryGetValue("Origin", out var origin)
            && origin != $"https://{ context.Request.Host.Value }")
        {
            return; // Refuse to handle request
        }
    }
    await next();
});

3。授权

我已经在此应用程序中使用基于 OIDC cookie 的身份验证,因此似乎值得对 Blazor 端点应用授权,以便只有经过身份验证的用户才能访问它。值得注意的是,这本身并不能防止跨源攻击,这种攻击可能会以某种方式让经过身份验证的用户访问连接到我们 Blazor 端点的 运行 代码,因为 OIDC cookie 是 SameSite=None出于必要。不过,这似乎是值得应用的附加保护。

这是通过将 .RequireAuthorization() 添加到 MapBlazorHub() 来实现的。

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub()
        .RequireAuthorization()
        .WithMetadata(new DisableCorsAttribute());
    endpoints.MapFallbackToPage("/_Host");
});