Considerações de segurança no ASP.NET Core SignalR

Por Andrew Stanton-Nurse

Esse artigo fornece informações sobre como proteger o SignalR.

Compartilhamento de recurso entre origens

O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para permitir conexões SignalR entre origens no navegador. Se o código JavaScript estiver hospedado em um domínio diferente do aplicativo SignalR, o middleware CORS deverá ser habilitado para permitir que o JavaScript se conecte ao aplicativo SignalR. Permitir solicitações entre origens somente de domínios em que você confia ou controla. Por exemplo:

  • Seu site está hospedado no http://www.example.com
  • Seu aplicativo SignalR está hospedado no http://signalr.example.com

O CORS deve ser configurado no aplicativo SignalR para permitir apenas a origem www.example.com.

Para obter informações sobre como configurar o CORS, consulte Habilitar Solicitações entre Origens (CORS). SignalRexige as seguintes políticas de CORS:

  • Permitir as origens esperadas específicas. Permitir qualquer origem é possível, mas não é seguro ou recomendado.
  • Métodos HTTP GET e POST devem ser permitidos.
  • As credenciais devem ser permitidas para que as sessões autoadesivas baseadas em cookie funcionem corretamente. Elas devem ser habilitados mesmo quando a autenticação não for usada.

No entanto, na versão 5.0, fornecemos a opção de não usar credenciais no cliente TypeScript. A opção de não usar credenciais só deve ser usada quando você tem certeza de que credenciais como Cookies não são necessárias em seu aplicativo (cookies são usadas pelo serviço de aplicativo do azure ao usar vários servidores para sessões autoadesivas).

Por exemplo, a política CORS destacada a seguir permite que um cliente do navegador SignalR hospedado no https://example.com acesse o aplicativo SignalR hospedado em https://signalr.example.com:

using SignalRChat.Hubs;

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy =>
                      {
                          policy.WithOrigins("http://example.com");
                          policy.WithMethods("GET", "POST");
                          policy.AllowCredentials();
                      });
});

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<ChatHub>("/chatHub");

No exemplo anterior, a política CORS é personalizada para permitir origens, métodos e credenciais específicos. Para obter mais informações sobre como personalizar políticas e middleware CORS no ASP.NET Core, consulte Middleware CORS: CORS com política nomeada e middleware.

Restrição de origem do WebSocket

As proteções fornecidas pelo CORS não se aplicam ao WebSockets. Para restrição de origem em WebSockets, leia Restrição de origem de WebSockets.

ConnectionId

Expor ConnectionId pode levar a usurpação de identidade mal-intencionada se a versão do servidor ou do cliente do SignalR for ASP.NET Core 2.2 ou anterior. Se o servidor e a versão do cliente SignalR forem ASP.NET Core 3.0 ou posteriores, o ConnectionToken em vez do ConnectionId deverá ser mantido em segredo. O ConnectionToken não é exposto propositalmente em nenhuma API. Pode ser difícil garantir que os clientes mais antigos do SignalR não estejam se conectando ao servidor, portanto, mesmo que a versão do seu servidor SignalR seja ASP.NET Core 3.0 ou posterior, o ConnectionId não deve ser exposto.

Log de token de acesso

Ao usar WebSockets ou eventos de Server-Sent, o cliente do navegador envia o token de acesso na cadeia de caracteres de consulta. O recebimento do token de acesso por meio da cadeia de caracteres de consulta geralmente é tão seguro quanto o uso do cabeçalho padrão Authorization . Sempre use HTTPS para garantir uma conexão segura de ponta a ponta entre o cliente e o servidor. Muitos servidores Web registram a URL de cada solicitação, incluindo a cadeia de caracteres de consulta. O registro em log das URLs pode registrar o token de acesso. ASP.NET Core registra a URL de cada solicitação por padrão, que inclui a cadeia de caracteres de consulta. Por exemplo:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/chathub?access_token=1234

Se você tiver preocupações sobre o registro em log desses dados com os logs do servidor, poderá desabilitar esse log inteiramente configurando o agente Microsoft.AspNetCore.Hosting para o nível Warning ou acima (essas mensagens são gravadas no nível Info). Para obter mais informações, consulte Aplicar regras de filtro de registro no código. Se você ainda quiser registrar determinadas informações de solicitação, poderá gravar middleware para registrar os dados necessários e filtrar o valor da cadeia de caracteres de consulta access_token (se presente).

Exceções

Geralmente, as mensagens de exceção são consideradas dados confidenciais e que não devem ser revelados a um cliente. Por padrão, o SignalR não envia ao cliente os detalhes de uma exceção gerada por um serviço gRPC. Em vez disso, o cliente recebe uma mensagem genérica indicando que ocorreu um erro. A entrega de mensagens de exceção para o cliente pode ser substituída (por exemplo, em desenvolvimento ou teste) por EnableDetailedErrors. As mensagens de exceção não devem ser expostas ao cliente em aplicativos de produção.

Gerenciamento de buffer

O SignalR usa buffers por conexão para gerenciar mensagens de entrada e saída. Por padrão, o SignalR limita esses buffers a 32 KB. O maior tamanho de mensagem que um cliente ou servidor pode enviar é 32 KB. A memória máxima consumida por uma conexão para mensagens é de 32 KB. Se suas mensagens forem sempre menores que 32 KB, você poderá reduzir o limite, o que:

  • Impede que um cliente possa enviar uma mensagem maior.
  • O servidor nunca precisará alocar buffers grandes para aceitar mensagens.

Se suas mensagens forem maiores que 32 KB, você poderá aumentar o limite. Aumentar esse limite significa:

  • Que e cliente pode fazer com que o servidor aloque buffers de memória grandes.
  • A alocação de servidor de buffers grandes pode reduzir o número de conexões simultâneas.

Há limites para mensagens de entrada e saída, ambas podem ser configuradas no objeto HttpConnectionDispatcherOptions configurado em MapHub:

  • ApplicationMaxBufferSize representa o número máximo de bytes do cliente que o servidor armazena em buffers. Se o cliente tentar enviar uma mensagem maior que esse limite, a conexão poderá ser fechada.
  • TransportMaxBufferSize representa o número máximo de bytes que o servidor pode enviar. Se o servidor tentar enviar uma mensagem (incluindo valores retornados de métodos de hub) maior que esse limite, uma exceção será gerada.

Definir o limite para 0 desabilita o limite. Remover o limite permite que um cliente envie uma mensagem de qualquer tamanho. Clientes mal-intencionados que enviam mensagens grandes podem fazer com que o excesso de memória seja alocado. O uso excessivo de memória pode reduzir significativamente o número de conexões simultâneas.

Esse artigo fornece informações sobre como proteger o SignalR.

Compartilhamento de recurso entre origens

O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para permitir conexões SignalR entre origens no navegador. Se o código JavaScript estiver hospedado em um domínio diferente do aplicativo SignalR, o middleware CORS deverá ser habilitado para permitir que o JavaScript se conecte ao aplicativo SignalR. Permitir solicitações entre origens somente de domínios em que você confia ou controla. Por exemplo:

  • Seu site está hospedado no http://www.example.com
  • Seu aplicativo SignalR está hospedado no http://signalr.example.com

O CORS deve ser configurado no aplicativo SignalR para permitir apenas a origem www.example.com.

Para obter informações sobre como configurar o CORS, consulte Habilitar Solicitações entre Origens (CORS). SignalRexige as seguintes políticas de CORS:

  • Permitir as origens esperadas específicas. Permitir qualquer origem é possível, mas não é seguro ou recomendado.
  • Métodos HTTP GET e POST devem ser permitidos.
  • As credenciais devem ser permitidas para que as sessões autoadesivas baseadas em cookie funcionem corretamente. Elas devem ser habilitados mesmo quando a autenticação não for usada.

No entanto, na versão 5.0, fornecemos a opção de não usar credenciais no cliente TypeScript. A opção de não usar credenciais só deve ser usada quando você tem certeza de que credenciais como Cookies não são necessárias em seu aplicativo (cookies são usadas pelo serviço de aplicativo do azure ao usar vários servidores para sessões autoadesivas).

Por exemplo, a política CORS destacada a seguir permite que um cliente do navegador SignalR hospedado no https://example.com acesse o aplicativo SignalR hospedado em https://signalr.example.com:

using SignalRChat.Hubs;

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy =>
                      {
                          policy.WithOrigins("http://example.com");
                          policy.WithMethods("GET", "POST");
                          policy.AllowCredentials();
                      });
});

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<ChatHub>("/chatHub");

No exemplo anterior, a política CORS é personalizada para permitir origens, métodos e credenciais específicos. Para obter mais informações sobre como personalizar políticas e middleware CORS no ASP.NET Core, consulte Middleware CORS: CORS com política nomeada e middleware.

Restrição de origem do WebSocket

As proteções fornecidas pelo CORS não se aplicam ao WebSockets. Para restrição de origem em WebSockets, leia Restrição de origem de WebSockets.

ConnectionId

Expor ConnectionId pode levar a usurpação de identidade mal-intencionada se a versão do servidor ou do cliente do SignalR for ASP.NET Core 2.2 ou anterior. Se o servidor e a versão do cliente SignalR forem ASP.NET Core 3.0 ou posteriores, o ConnectionToken em vez do ConnectionId deverá ser mantido em segredo. O ConnectionToken não é exposto propositalmente em nenhuma API. Pode ser difícil garantir que os clientes mais antigos do SignalR não estejam se conectando ao servidor, portanto, mesmo que a versão do seu servidor SignalR seja ASP.NET Core 3.0 ou posterior, o ConnectionId não deve ser exposto.

Log de token de acesso

Ao usar WebSockets ou eventos de Server-Sent, o cliente do navegador envia o token de acesso na cadeia de caracteres de consulta. O recebimento do token de acesso por meio da cadeia de caracteres de consulta geralmente é tão seguro quanto o uso do cabeçalho padrão Authorization . Sempre use HTTPS para garantir uma conexão segura de ponta a ponta entre o cliente e o servidor. Muitos servidores Web registram a URL de cada solicitação, incluindo a cadeia de caracteres de consulta. O registro em log das URLs pode registrar o token de acesso. ASP.NET Core registra a URL de cada solicitação por padrão, que inclui a cadeia de caracteres de consulta. Por exemplo:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/chathub?access_token=1234

Se você tiver preocupações sobre o registro em log desses dados com os logs do servidor, poderá desabilitar esse log inteiramente configurando o agente Microsoft.AspNetCore.Hosting para o nível Warning ou acima (essas mensagens são gravadas no nível Info). Para obter mais informações, consulte Aplicar regras de filtro de registro no código. Se você ainda quiser registrar determinadas informações de solicitação, poderá gravar middleware para registrar os dados necessários e filtrar o valor da cadeia de caracteres de consulta access_token (se presente).

Exceções

Geralmente, as mensagens de exceção são consideradas dados confidenciais e que não devem ser revelados a um cliente. Por padrão, o SignalR não envia ao cliente os detalhes de uma exceção gerada por um serviço gRPC. Em vez disso, o cliente recebe uma mensagem genérica indicando que ocorreu um erro. A entrega de mensagens de exceção para o cliente pode ser substituída (por exemplo, em desenvolvimento ou teste) por EnableDetailedErrors. As mensagens de exceção não devem ser expostas ao cliente em aplicativos de produção.

Gerenciamento de buffer

O SignalR usa buffers por conexão para gerenciar mensagens de entrada e saída. Por padrão, o SignalR limita esses buffers a 32 KB. O maior tamanho de mensagem que um cliente ou servidor pode enviar é 32 KB. A memória máxima consumida por uma conexão para mensagens é de 32 KB. Se suas mensagens forem sempre menores que 32 KB, você poderá reduzir o limite, o que:

  • Impede que um cliente possa enviar uma mensagem maior.
  • O servidor nunca precisará alocar buffers grandes para aceitar mensagens.

Se suas mensagens forem maiores que 32 KB, você poderá aumentar o limite. Aumentar esse limite significa:

  • Que e cliente pode fazer com que o servidor aloque buffers de memória grandes.
  • A alocação de servidor de buffers grandes pode reduzir o número de conexões simultâneas.

Há limites para mensagens de entrada e saída, ambas podem ser configuradas no objeto HttpConnectionDispatcherOptions configurado em MapHub:

  • ApplicationMaxBufferSize representa o número máximo de bytes do cliente que o servidor armazena em buffers. Se o cliente tentar enviar uma mensagem maior que esse limite, a conexão poderá ser fechada.
  • TransportMaxBufferSize representa o número máximo de bytes que o servidor pode enviar. Se o servidor tentar enviar uma mensagem (incluindo valores retornados de métodos de hub) maior que esse limite, uma exceção será gerada.

Definir o limite para 0 desabilita o limite. Remover o limite permite que um cliente envie uma mensagem de qualquer tamanho. Clientes mal-intencionados que enviam mensagens grandes podem fazer com que o excesso de memória seja alocado. O uso excessivo de memória pode reduzir significativamente o número de conexões simultâneas.

Esse artigo fornece informações sobre como proteger o SignalR.

Compartilhamento de recurso entre origens

O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para permitir conexões SignalR entre origens no navegador. Se o código JavaScript estiver hospedado em um domínio diferente do aplicativo SignalR, o middleware CORS deverá ser habilitado para permitir que o JavaScript se conecte ao aplicativo SignalR. Permitir solicitações entre origens somente de domínios em que você confia ou controla. Por exemplo:

  • Seu site está hospedado no http://www.example.com
  • Seu aplicativo SignalR está hospedado no http://signalr.example.com

O CORS deve ser configurado no aplicativo SignalR para permitir apenas a origem www.example.com.

Para obter informações sobre como configurar o CORS, consulte Habilitar Solicitações entre Origens (CORS). SignalRexige as seguintes políticas de CORS:

  • Permitir as origens esperadas específicas. Permitir qualquer origem é possível, mas não é seguro ou recomendado.
  • Métodos HTTP GET e POST devem ser permitidos.
  • As credenciais devem ser permitidas para que as sessões autoadesivas baseadas em cookie funcionem corretamente. Elas devem ser habilitados mesmo quando a autenticação não for usada.

No entanto, na versão 5.0, fornecemos a opção de não usar credenciais no cliente TypeScript. A opção de não usar credenciais só deve ser usada quando você tem certeza de que credenciais como Cookies não são necessárias em seu aplicativo (cookies são usadas pelo serviço de aplicativo do azure ao usar vários servidores para sessões autoadesivas).

Por exemplo, a política CORS destacada a seguir permite que um cliente do navegador SignalR hospedado no https://example.com acesse o aplicativo SignalR hospedado em https://signalr.example.com:

using SignalRChat.Hubs;

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy =>
                      {
                          policy.WithOrigins("http://example.com");
                          policy.WithMethods("GET", "POST");
                          policy.AllowCredentials();
                      });
});

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<ChatHub>("/chatHub");

No exemplo anterior, a política CORS é personalizada para permitir origens, métodos e credenciais específicos. Para obter mais informações sobre como personalizar políticas e middleware CORS no ASP.NET Core, consulte Middleware CORS: CORS com política nomeada e middleware.

Restrição de origem do WebSocket

As proteções fornecidas pelo CORS não se aplicam ao WebSockets. Para restrição de origem em WebSockets, leia Restrição de origem de WebSockets.

ConnectionId

Expor ConnectionId pode levar a usurpação de identidade mal-intencionada se a versão do servidor ou do cliente do SignalR for ASP.NET Core 2.2 ou anterior. Se o servidor e a versão do cliente SignalR forem ASP.NET Core 3.0 ou posteriores, o ConnectionToken em vez do ConnectionId deverá ser mantido em segredo. O ConnectionToken não é exposto propositalmente em nenhuma API. Pode ser difícil garantir que os clientes mais antigos do SignalR não estejam se conectando ao servidor, portanto, mesmo que a versão do seu servidor SignalR seja ASP.NET Core 3.0 ou posterior, o ConnectionId não deve ser exposto.

Log de token de acesso

Ao usar WebSockets ou eventos de Server-Sent, o cliente do navegador envia o token de acesso na cadeia de caracteres de consulta. O recebimento do token de acesso por meio da cadeia de caracteres de consulta geralmente é tão seguro quanto o uso do cabeçalho padrão Authorization . Sempre use HTTPS para garantir uma conexão segura de ponta a ponta entre o cliente e o servidor. Muitos servidores Web registram a URL de cada solicitação, incluindo a cadeia de caracteres de consulta. O registro em log das URLs pode registrar o token de acesso. ASP.NET Core registra a URL de cada solicitação por padrão, que inclui a cadeia de caracteres de consulta. Por exemplo:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/chathub?access_token=1234

Se você tiver preocupações sobre o registro em log desses dados com os logs do servidor, poderá desabilitar esse log inteiramente configurando o agente Microsoft.AspNetCore.Hosting para o nível Warning ou acima (essas mensagens são gravadas no nível Info). Para obter mais informações, consulte Aplicar regras de filtro de registro no código. Se você ainda quiser registrar determinadas informações de solicitação, poderá gravar middleware para registrar os dados necessários e filtrar o valor da cadeia de caracteres de consulta access_token (se presente).

Exceções

Geralmente, as mensagens de exceção são consideradas dados confidenciais e que não devem ser revelados a um cliente. Por padrão, o SignalR não envia ao cliente os detalhes de uma exceção gerada por um serviço gRPC. Em vez disso, o cliente recebe uma mensagem genérica indicando que ocorreu um erro. A entrega de mensagens de exceção para o cliente pode ser substituída (por exemplo, em desenvolvimento ou teste) por EnableDetailedErrors. As mensagens de exceção não devem ser expostas ao cliente em aplicativos de produção.

Gerenciamento de buffer

O SignalR usa buffers por conexão para gerenciar mensagens de entrada e saída. Por padrão, o SignalR limita esses buffers a 32 KB. O maior tamanho de mensagem que um cliente ou servidor pode enviar é 32 KB. A memória máxima consumida por uma conexão para mensagens é de 32 KB. Se suas mensagens forem sempre menores que 32 KB, você poderá reduzir o limite, o que:

  • Impede que um cliente possa enviar uma mensagem maior.
  • O servidor nunca precisará alocar buffers grandes para aceitar mensagens.

Se suas mensagens forem maiores que 32 KB, você poderá aumentar o limite. Aumentar esse limite significa:

  • Que e cliente pode fazer com que o servidor aloque buffers de memória grandes.
  • A alocação de servidor de buffers grandes pode reduzir o número de conexões simultâneas.

Há limites para mensagens de entrada e saída, ambas podem ser configuradas no objeto HttpConnectionDispatcherOptions configurado em MapHub:

  • ApplicationMaxBufferSize representa o número máximo de bytes do cliente que o servidor armazena em buffers. Se o cliente tentar enviar uma mensagem maior que esse limite, a conexão poderá ser fechada.
  • TransportMaxBufferSize representa o número máximo de bytes que o servidor pode enviar. Se o servidor tentar enviar uma mensagem (incluindo valores retornados de métodos de hub) maior que esse limite, uma exceção será gerada.

Definir o limite para 0 desabilita o limite. Remover o limite permite que um cliente envie uma mensagem de qualquer tamanho. Clientes mal-intencionados que enviam mensagens grandes podem fazer com que o excesso de memória seja alocado. O uso excessivo de memória pode reduzir significativamente o número de conexões simultâneas.

Esse artigo fornece informações sobre como proteger o SignalR.

Compartilhamento de recurso entre origens

O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para permitir conexões SignalR entre origens no navegador. Se o código JavaScript estiver hospedado em um domínio diferente do aplicativo SignalR, o middleware CORS deverá ser habilitado para permitir que o JavaScript se conecte ao aplicativo SignalR. Permitir solicitações entre origens somente de domínios em que você confia ou controla. Por exemplo:

  • Seu site está hospedado no http://www.example.com
  • Seu aplicativo SignalR está hospedado no http://signalr.example.com

O CORS deve ser configurado no aplicativo SignalR para permitir apenas a origem www.example.com.

Para obter informações sobre como configurar o CORS, consulte Habilitar Solicitações entre Origens (CORS). SignalRexige as seguintes políticas de CORS:

  • Permitir as origens esperadas específicas. Permitir qualquer origem é possível, mas não é seguro ou recomendado.
  • Métodos HTTP GET e POST devem ser permitidos.
  • As credenciais devem ser permitidas para que as sessões autoadesivas baseadas em cookie funcionem corretamente. Elas devem ser habilitados mesmo quando a autenticação não for usada.

No entanto, na versão 5.0, fornecemos a opção de não usar credenciais no cliente TypeScript. A opção de não usar credenciais só deve ser usada quando você tem certeza de que credenciais como Cookies não são necessárias em seu aplicativo (cookies são usadas pelo serviço de aplicativo do azure ao usar vários servidores para sessões autoadesivas).

Por exemplo, a política CORS a seguir permite que um cliente do navegador SignalR hospedado no https://example.com acesse o aplicativo SignalR hospedado em https://signalr.example.com:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ... other middleware ...

    // Make sure the CORS middleware is ahead of SignalR.
    app.UseCors(builder =>
    {
        builder.WithOrigins("https://example.com")
            .AllowAnyHeader()
            .WithMethods("GET", "POST")
            .AllowCredentials();
    });

    // ... other middleware ...
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chathub");
    });

    // ... other middleware ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ... other middleware ...

    // Make sure the CORS middleware is ahead of SignalR.
    app.UseCors(builder =>
    {
        builder.WithOrigins("https://example.com")
            .AllowAnyHeader()
            .WithMethods("GET", "POST")
            .AllowCredentials();
    });

    // ... other middleware ...

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("/chathub");
    });

    // ... other middleware ...
}

Restrição de origem do WebSocket

As proteções fornecidas pelo CORS não se aplicam ao WebSockets. Para restrição de origem em WebSockets, leia Restrição de origem de WebSockets.

As proteções fornecidas pelo CORS não se aplicam ao WebSockets. Navegadores não:

  • Executam solicitações de simulação de CORS.
  • Respeitam as restrições especificadas em cabeçalhos Access-Control ao fazer solicitações de WebSocket.

No entanto, os navegadores enviam o cabeçalho Origin ao emitir solicitações de WebSocket. Os aplicativos devem ser configurados para validar esses cabeçalhos e garantir que apenas WebSockets provenientes de origens esperadas sejam permitidos.

No ASP.NET Core 2.1 e posterior, a validação de cabeçalho pode ser obtida usando um middleware personalizado colocado antes de UseSignalR e de middleware de autenticação em Configure:


// In Startup, add a static field listing the allowed Origin values:
private static readonly HashSet<string> _allowedOrigins = new HashSet<string>()
{
    // Add allowed origins here. For example:
    "https://www.mysite.com",
    "https://mysite.com",
};

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ... other middleware ...

    // Validate Origin header on WebSocket requests to prevent unexpected cross-site 
    // WebSocket requests.
    app.Use((context, next) =>
    {
        // Check for a WebSocket request.
        if (string.Equals(context.Request.Headers["Upgrade"], "websocket"))
        {
            var origin = context.Request.Headers["Origin"];

            // If there is an origin header, and the origin header doesn't match 
            // an allowed value:
            if (!string.IsNullOrEmpty(origin) && !_allowedOrigins.Contains(origin))
            {
                // The origin is not allowed, reject the request
                context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
                return Task.CompletedTask;
            }
        }

        // The request is a valid Origin or not a WebSocket request, so continue.
        return next();
    });

    // ... other middleware ...

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("/chathub");
    });

    // ... other middleware ...
}

Observação

O cabeçalho Origin é controlado pelo cliente e, como o cabeçalho Referer, pode ser falsificado. Esses cabeçalhos não devem ser usados como um mecanismo de autenticação.

ConnectionId

Expor ConnectionId pode levar a usurpação de identidade mal-intencionada se a versão do servidor ou do cliente do SignalR for ASP.NET Core 2.2 ou anterior. Se o servidor e a versão do cliente SignalR forem ASP.NET Core 3.0 ou posteriores, o ConnectionToken em vez do ConnectionId deverá ser mantido em segredo. O ConnectionToken não é exposto propositalmente em nenhuma API. Pode ser difícil garantir que os clientes mais antigos do SignalR não estejam se conectando ao servidor, portanto, mesmo que a versão do seu servidor SignalR seja ASP.NET Core 3.0 ou posterior, o ConnectionId não deve ser exposto.

Log de token de acesso

Ao usar WebSockets ou eventos de Server-Sent, o cliente do navegador envia o token de acesso na cadeia de caracteres de consulta. O recebimento do token de acesso por meio da cadeia de caracteres de consulta geralmente é tão seguro quanto o uso do cabeçalho padrão Authorization . Sempre use HTTPS para garantir uma conexão segura de ponta a ponta entre o cliente e o servidor. Muitos servidores Web registram a URL de cada solicitação, incluindo a cadeia de caracteres de consulta. O registro em log das URLs pode registrar o token de acesso. ASP.NET Core registra a URL de cada solicitação por padrão, que inclui a cadeia de caracteres de consulta. Por exemplo:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/chathub?access_token=1234

Se você tiver preocupações sobre o registro em log desses dados com os logs do servidor, poderá desabilitar esse log inteiramente configurando o agente Microsoft.AspNetCore.Hosting para o nível Warning ou acima (essas mensagens são gravadas no nível Info). Para obter mais informações, consulte Aplicar regras de filtro de registro no código. Se você ainda quiser registrar determinadas informações de solicitação, poderá gravar middleware para registrar os dados necessários e filtrar o valor da cadeia de caracteres de consulta access_token (se presente).

Exceções

Geralmente, as mensagens de exceção são consideradas dados confidenciais e que não devem ser revelados a um cliente. Por padrão, o SignalR não envia ao cliente os detalhes de uma exceção gerada por um serviço gRPC. Em vez disso, o cliente recebe uma mensagem genérica indicando que ocorreu um erro. A entrega de mensagens de exceção para o cliente pode ser substituída (por exemplo, em desenvolvimento ou teste) por EnableDetailedErrors. As mensagens de exceção não devem ser expostas ao cliente em aplicativos de produção.

Gerenciamento de buffer

O SignalR usa buffers por conexão para gerenciar mensagens de entrada e saída. Por padrão, o SignalR limita esses buffers a 32 KB. O maior tamanho de mensagem que um cliente ou servidor pode enviar é 32 KB. A memória máxima consumida por uma conexão para mensagens é de 32 KB. Se suas mensagens forem sempre menores que 32 KB, você poderá reduzir o limite, o que:

  • Impede que um cliente possa enviar uma mensagem maior.
  • O servidor nunca precisará alocar buffers grandes para aceitar mensagens.

Se suas mensagens forem maiores que 32 KB, você poderá aumentar o limite. Aumentar esse limite significa:

  • Que e cliente pode fazer com que o servidor aloque buffers de memória grandes.
  • A alocação de servidor de buffers grandes pode reduzir o número de conexões simultâneas.

Há limites para mensagens de entrada e saída, ambas podem ser configuradas no objeto HttpConnectionDispatcherOptions configurado em MapHub:

  • ApplicationMaxBufferSize representa o número máximo de bytes do cliente que o servidor armazena em buffers. Se o cliente tentar enviar uma mensagem maior que esse limite, a conexão poderá ser fechada.
  • TransportMaxBufferSize representa o número máximo de bytes que o servidor pode enviar. Se o servidor tentar enviar uma mensagem (incluindo valores retornados de métodos de hub) maior que esse limite, uma exceção será gerada.

Definir o limite para 0 desabilita o limite. Remover o limite permite que um cliente envie uma mensagem de qualquer tamanho. Clientes mal-intencionados que enviam mensagens grandes podem fazer com que o excesso de memória seja alocado. O uso excessivo de memória pode reduzir significativamente o número de conexões simultâneas.