ASP.NET Core 中的安全注意事项 SignalRSecurity considerations in ASP.NET Core SignalR
本文提供了有关保护 SignalR的信息。
可用于允许在浏览器中进行跨域 SignalR 连接。如果 JavaScript 代码托管在 SignalR 应用的另一个域中,则必须启用CORS 中间件才能使 JavaScript 连接到 SignalR 应用。仅允许来自你信任或控制的域的跨域请求。例如:
- 网站托管在
- SignalR 应用承载于
应在 SignalR 应用程序中配置 CORS,以只允许源 www.example.com
。
有关配置 CORS 的详细信息,请参阅启用跨域请求(CORS)。 SignalR需要以下 CORS 策略:
- 允许特定的预期来源。允许任何来源是可行的,但不安全或不推荐使用。
- 必须允许
GET
和POST
的 HTTP 方法。 - 若要使基于 cookie 的粘滞会话正常工作,必须允许使用凭据。即使未使用身份验证,也必须启用它们。
例如,以下 CORS 策略允许
上承载的 SignalR 浏览器客户端访问
https://signalr.example.com
上承载的 SignalR 应用程序:
备注
SignalR 与 Azure App Service 中的内置 CORS 功能不兼容。
WebSocket 源限制WebSocket Origin Restriction
CORS 提供的保护不适用于 WebSocket。浏览器不会:
- 执行 CORS 预检请求。
但是,浏览器在发出 WebSocket 请求时会发送 Origin
标头。应将应用程序配置为验证这些标头,以确保只允许来自预期来源的 WebSocket。
在 ASP.NET Core 2.1 及更高版本中,可以使用在 之前放置的自定义中间件和 Configure
中的身份验证中间件来实现标题验证:
备注
与 Origin
标头一样,Referer
标头由客户端控制,并可以伪造。这些标头不应用作身份验证机制。
如果 SignalR 服务器或客户端版本 ASP.NET Core 2.2 或更早版本,公开 ConnectionId
可能会导致恶意模拟。如果 SignalR 服务器和客户端版本 ASP.NET Core 3.0 或更高版本,则 ConnectionToken
,而不是 ConnectionId
必须保持机密。不会在任何 API 中公开 ConnectionToken
。很难确保较旧的 SignalR 客户端未连接到服务器,因此即使 SignalR 服务器版本 ASP.NET Core 3.0 或更高版本,也不应公开 ConnectionId
。
访问令牌日志记录Access token logging
如果你对将此数据与服务器日志进行日志记录有关,你可以通过将 Microsoft.AspNetCore.Hosting
记录器配置到 Warning
级别或更高级别来完全禁用此日志记录(这些消息在 Info
级别写入)。有关详细信息,请参阅。如果仍想记录某些请求信息,可以编写中间件来记录所需的数据,并筛选出 access_token
查询字符串值(如果存在)。
异常消息通常被视为不应泄露给客户端的敏感数据。默认情况下,SignalR 不会将集线器方法引发的异常的详细信息发送到客户端。相反,客户端将收到一条指示出错的一般消息。向客户端发送的异常消息可以通过重写(例如,在开发或测试中)。不应在生产应用程序中向客户端公开异常消息。
缓冲区管理Buffer management
SignalR 使用每个连接的缓冲区来管理传入消息和传出消息。默认情况下,SignalR 会将这些缓冲区限制为 32 KB。客户端或服务器可以发送的最大消息为 32 KB。消息连接使用的最大内存为 32 KB。如果消息始终小于 32 KB,则可以减少限制:
- 禁止客户端发送更大的消息。
- 服务器绝不会需要分配大型缓冲区来接受消息。
如果消息大小超过 32 KB,则可以增加限制。增加此限制意味着:
- 客户端可能会导致服务器分配大的内存缓冲区。
- 大缓冲区的服务器分配可能会减少并发连接的数量。
传入消息和传出消息有限制,可以在 MapHub
中配置的对象上进行配置:
ApplicationMaxBufferSize
表示从客户端缓冲的最大字节数。如果客户端尝试发送比此限制更大的消息,则可能会关闭该连接。TransportMaxBufferSize
表示服务器可以发送的最大字节数。如果服务器尝试发送的消息(包括从集线器方法返回的值)大于此限制,则会引发异常。
将限制设置为 0
会禁用限制。通过删除该限制,客户端可以发送任意大小的消息。发送大消息的恶意客户端可能会导致分配额外的内存。过度使用内存会显著减少并发连接数。