Condividi tramite


Considerazioni sulla sicurezza in ASP.NET Core SignalR

Di Andrew Stanton-Nurse

Questo articolo fornisce informazioni sulla protezione di SignalR.

Condivisione di risorse tra le origini

La condivisione di risorse tra le origini (CORS) può essere usata per consentire le connessioni tra le origini SignalR nel browser. Se il codice JavaScript è ospitato in un dominio diverso dall'app SignalR , il middleware CORS deve essere abilitato per consentire a JavaScript di connettersi all'app SignalR . Consenti richieste tra le origini solo dai domini attendibili o controllati. Ad esempio:

  • Il sito è ospitato in http://www.example.com
  • L'app SignalR è ospitata in http://signalr.example.com

CORS deve essere configurato nell'app SignalR per consentire solo l'origine www.example.com.

Per altre informazioni sulla configurazione di CORS, vedere Abilitare le richieste tra origini (CORS). SignalRrichiede i criteri CORS seguenti:

  • Consente le origini previste specifiche. È possibile consentire qualsiasi origine, ma non è sicura o consigliata.
  • I metodi GET HTTP e POST devono essere consentiti.
  • Le credenziali devono essere consentite affinché cookiele sessioni permanenti basate su funzionino correttamente. Devono essere abilitati anche quando l'autenticazione non viene usata.

Tuttavia, nella versione 5.0 è stata fornita un'opzione nel client TypeScript per non usare le credenziali. L'opzione per non usare le credenziali deve essere usata solo quando si conosce il 100% che le credenziali come i cookie non sono necessarie nell'app (i cookie vengono usati dal servizio app di Azure quando si usano più server per sessioni permanenti).

Ad esempio, i criteri CORS evidenziati seguenti consentono a un SignalR client del browser ospitato in https://example.com di accedere all'app SignalR ospitata in 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");

Nell'esempio precedente, i criteri CORS vengono personalizzati per consentire origini, metodi e credenziali specifici. Per altre informazioni sulla personalizzazione dei criteri CORS e del middleware in ASP.NET Core, vedere Middleware CORS: CORS con criteri e middleware denominati.

Restrizione dell'origine WebSocket

La protezione fornita da CORS non si applica agli oggetti WebSocket. Per la restrizione dell'origine nei WebSocket, vedere Restrizione dell'origine WebSocket.

ID connessione

L'esposizione ConnectionId può causare la rappresentazione dannosa se la versione del server o del SignalR client è ASP.NET Core 2.2 o versioni precedenti. Se il server e la SignalR versione client sono ASP.NET Core 3.0 o versione successiva, il ConnectionToken anziché deve ConnectionId essere mantenuto segreto. l'oggetto ConnectionToken non è esposto in alcuna API. Può essere difficile assicurarsi che i client meno recenti SignalR non si connettano al server, quindi anche se la SignalR versione del server è ASP.NET Core 3.0 o versione successiva, l'oggetto ConnectionId non deve essere esposto.

Registrazione dei token di accesso

Quando si usano WebSocket o Eventi inviati dal server, il client del browser invia il token di accesso nella stringa di query. La ricezione del token di accesso tramite la stringa di query è in genere sicura come l'uso dell'intestazione standard Authorization . Usare sempre HTTPS per garantire una connessione end-to-end sicura tra il client e il server. Molti server Web registrano l'URL per ogni richiesta, inclusa la stringa di query. La registrazione degli URL può registrare il token di accesso. ASP.NET Core registra l'URL per ogni richiesta per impostazione predefinita, che include la stringa di query. Ad esempio:

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

In caso di dubbi sulla registrazione di questi dati con i log del server, è possibile disabilitare completamente questa registrazione configurando il Microsoft.AspNetCore.Hosting logger al Warning livello o superiore (questi messaggi vengono scritti a Info livello). Per altre informazioni, vedere Applicare le regole di filtro dei log nel codice . Se si desidera comunque registrare determinate informazioni sulla richiesta, è possibile scrivere middleware per registrare i dati necessari e filtrare il valore della access_token stringa di query (se presente).

Eccezioni

I messaggi di eccezione sono in genere considerati dati sensibili che non devono essere rivelati a un client. Per impostazione predefinita, SignalR non invia i dettagli di un'eccezione generata da un metodo hub al client. Il client riceve invece un messaggio generico che indica che si è verificato un errore. Il recapito dei messaggi di eccezione al client può essere sottoposto a override (ad esempio in fase di sviluppo o test) con EnableDetailedErrors. I messaggi di eccezione non devono essere esposti al client nelle app di produzione.

Gestione del buffer

SignalR usa buffer per connessione per gestire i messaggi in ingresso e in uscita. Per impostazione predefinita, SignalR limita questi buffer a 32 KB. Il messaggio più grande che un client o un server può inviare è 32 KB. La memoria massima utilizzata da una connessione per i messaggi è di 32 KB. Se i messaggi sono sempre inferiori a 32 KB, è possibile ridurre il limite, che:

  • Impedisce a un client di inviare un messaggio più grande.
  • Il server non dovrà mai allocare buffer di grandi dimensioni per accettare messaggi.

Se i messaggi superano i 32 KB, è possibile aumentare il limite. L'aumento di questo limite significa:

  • Il client può causare l'allocazione di buffer di memoria di grandi dimensioni da parte del server.
  • L'allocazione del server di buffer di grandi dimensioni può ridurre il numero di connessioni simultanee.

Esistono limiti per i messaggi in ingresso e in uscita, entrambi possono essere configurati nell'oggetto HttpConnectionDispatcherOptions configurato in MapHub:

  • ApplicationMaxBufferSize rappresenta il numero massimo di byte dal client memorizzato nel buffer del server. Se il client tenta di inviare un messaggio superiore a questo limite, la connessione potrebbe essere chiusa.
  • TransportMaxBufferSize rappresenta il numero massimo di byte che il server può inviare. Se il server tenta di inviare un messaggio (inclusi i valori restituiti dai metodi hub) maggiore di questo limite, verrà generata un'eccezione.

L'impostazione del limite per 0 disabilitare il limite. La rimozione del limite consente a un client di inviare un messaggio di qualsiasi dimensione. I client malintenzionati che inviano messaggi di grandi dimensioni possono causare l'allocazione della memoria in eccesso. L'utilizzo eccessivo della memoria può ridurre significativamente il numero di connessioni simultanee.

Questo articolo fornisce informazioni sulla protezione di SignalR.

Condivisione di risorse tra le origini

La condivisione di risorse tra le origini (CORS) può essere usata per consentire le connessioni tra le origini SignalR nel browser. Se il codice JavaScript è ospitato in un dominio diverso dall'app SignalR , il middleware CORS deve essere abilitato per consentire a JavaScript di connettersi all'app SignalR . Consenti richieste tra le origini solo dai domini attendibili o controllati. Ad esempio:

  • Il sito è ospitato in http://www.example.com
  • L'app SignalR è ospitata in http://signalr.example.com

CORS deve essere configurato nell'app SignalR per consentire solo l'origine www.example.com.

Per altre informazioni sulla configurazione di CORS, vedere Abilitare le richieste tra origini (CORS). SignalRrichiede i criteri CORS seguenti:

  • Consente le origini previste specifiche. È possibile consentire qualsiasi origine, ma non è sicura o consigliata.
  • I metodi GET HTTP e POST devono essere consentiti.
  • Le credenziali devono essere consentite affinché cookiele sessioni permanenti basate su funzionino correttamente. Devono essere abilitati anche quando l'autenticazione non viene usata.

Tuttavia, nella versione 5.0 è stata fornita un'opzione nel client TypeScript per non usare le credenziali. L'opzione per non usare le credenziali deve essere usata solo quando si conosce il 100% che le credenziali come i cookie non sono necessarie nell'app (i cookie vengono usati dal servizio app di Azure quando si usano più server per sessioni permanenti).

Ad esempio, i criteri CORS evidenziati seguenti consentono a un SignalR client del browser ospitato in https://example.com di accedere all'app SignalR ospitata in 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");

Nell'esempio precedente, i criteri CORS vengono personalizzati per consentire origini, metodi e credenziali specifici. Per altre informazioni sulla personalizzazione dei criteri CORS e del middleware in ASP.NET Core, vedere Middleware CORS: CORS con criteri e middleware denominati.

Restrizione dell'origine WebSocket

La protezione fornita da CORS non si applica agli oggetti WebSocket. Per la restrizione dell'origine nei WebSocket, vedere Restrizione dell'origine WebSocket.

ID connessione

L'esposizione ConnectionId può causare la rappresentazione dannosa se la versione del server o del SignalR client è ASP.NET Core 2.2 o versioni precedenti. Se il server e la SignalR versione client sono ASP.NET Core 3.0 o versione successiva, il ConnectionToken anziché deve ConnectionId essere mantenuto segreto. l'oggetto ConnectionToken non è esposto in alcuna API. Può essere difficile assicurarsi che i client meno recenti SignalR non si connettano al server, quindi anche se la SignalR versione del server è ASP.NET Core 3.0 o versione successiva, l'oggetto ConnectionId non deve essere esposto.

Registrazione dei token di accesso

Quando si usano WebSocket o Eventi inviati dal server, il client del browser invia il token di accesso nella stringa di query. La ricezione del token di accesso tramite la stringa di query è in genere sicura come l'uso dell'intestazione standard Authorization . Usare sempre HTTPS per garantire una connessione end-to-end sicura tra il client e il server. Molti server Web registrano l'URL per ogni richiesta, inclusa la stringa di query. La registrazione degli URL può registrare il token di accesso. ASP.NET Core registra l'URL per ogni richiesta per impostazione predefinita, che include la stringa di query. Ad esempio:

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

In caso di dubbi sulla registrazione di questi dati con i log del server, è possibile disabilitare completamente questa registrazione configurando il Microsoft.AspNetCore.Hosting logger al Warning livello o superiore (questi messaggi vengono scritti a Info livello). Per altre informazioni, vedere Applicare le regole di filtro dei log nel codice . Se si desidera comunque registrare determinate informazioni sulla richiesta, è possibile scrivere middleware per registrare i dati necessari e filtrare il valore della access_token stringa di query (se presente).

Eccezioni

I messaggi di eccezione sono in genere considerati dati sensibili che non devono essere rivelati a un client. Per impostazione predefinita, SignalR non invia i dettagli di un'eccezione generata da un metodo hub al client. Il client riceve invece un messaggio generico che indica che si è verificato un errore. Il recapito dei messaggi di eccezione al client può essere sottoposto a override (ad esempio in fase di sviluppo o test) con EnableDetailedErrors. I messaggi di eccezione non devono essere esposti al client nelle app di produzione.

Gestione del buffer

SignalR usa buffer per connessione per gestire i messaggi in ingresso e in uscita. Per impostazione predefinita, SignalR limita questi buffer a 32 KB. Il messaggio più grande che un client o un server può inviare è 32 KB. La memoria massima utilizzata da una connessione per i messaggi è di 32 KB. Se i messaggi sono sempre inferiori a 32 KB, è possibile ridurre il limite, che:

  • Impedisce a un client di inviare un messaggio più grande.
  • Il server non dovrà mai allocare buffer di grandi dimensioni per accettare messaggi.

Se i messaggi superano i 32 KB, è possibile aumentare il limite. L'aumento di questo limite significa:

  • Il client può causare l'allocazione di buffer di memoria di grandi dimensioni da parte del server.
  • L'allocazione del server di buffer di grandi dimensioni può ridurre il numero di connessioni simultanee.

Esistono limiti per i messaggi in ingresso e in uscita, entrambi possono essere configurati nell'oggetto HttpConnectionDispatcherOptions configurato in MapHub:

  • ApplicationMaxBufferSize rappresenta il numero massimo di byte dal client memorizzato nel buffer del server. Se il client tenta di inviare un messaggio superiore a questo limite, la connessione potrebbe essere chiusa.
  • TransportMaxBufferSize rappresenta il numero massimo di byte che il server può inviare. Se il server tenta di inviare un messaggio (inclusi i valori restituiti dai metodi hub) maggiore di questo limite, verrà generata un'eccezione.

L'impostazione del limite per 0 disabilitare il limite. La rimozione del limite consente a un client di inviare un messaggio di qualsiasi dimensione. I client malintenzionati che inviano messaggi di grandi dimensioni possono causare l'allocazione della memoria in eccesso. L'utilizzo eccessivo della memoria può ridurre significativamente il numero di connessioni simultanee.

Questo articolo fornisce informazioni sulla protezione di SignalR.

Condivisione di risorse tra le origini

La condivisione di risorse tra le origini (CORS) può essere usata per consentire le connessioni tra le origini SignalR nel browser. Se il codice JavaScript è ospitato in un dominio diverso dall'app SignalR , il middleware CORS deve essere abilitato per consentire a JavaScript di connettersi all'app SignalR . Consenti richieste tra le origini solo dai domini attendibili o controllati. Ad esempio:

  • Il sito è ospitato in http://www.example.com
  • L'app SignalR è ospitata in http://signalr.example.com

CORS deve essere configurato nell'app SignalR per consentire solo l'origine www.example.com.

Per altre informazioni sulla configurazione di CORS, vedere Abilitare le richieste tra origini (CORS). SignalRrichiede i criteri CORS seguenti:

  • Consente le origini previste specifiche. È possibile consentire qualsiasi origine, ma non è sicura o consigliata.
  • I metodi GET HTTP e POST devono essere consentiti.
  • Le credenziali devono essere consentite affinché cookiele sessioni permanenti basate su funzionino correttamente. Devono essere abilitati anche quando l'autenticazione non viene usata.

Tuttavia, nella versione 5.0 è stata fornita un'opzione nel client TypeScript per non usare le credenziali. L'opzione per non usare le credenziali deve essere usata solo quando si conosce il 100% che le credenziali come i cookie non sono necessarie nell'app (i cookie vengono usati dal servizio app di Azure quando si usano più server per sessioni permanenti).

Ad esempio, i criteri CORS evidenziati seguenti consentono a un SignalR client del browser ospitato in https://example.com di accedere all'app SignalR ospitata in 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");

Nell'esempio precedente, i criteri CORS vengono personalizzati per consentire origini, metodi e credenziali specifici. Per altre informazioni sulla personalizzazione dei criteri CORS e del middleware in ASP.NET Core, vedere Middleware CORS: CORS con criteri e middleware denominati.

Restrizione dell'origine WebSocket

La protezione fornita da CORS non si applica agli oggetti WebSocket. Per la restrizione dell'origine nei WebSocket, vedere Restrizione dell'origine WebSocket.

ID connessione

L'esposizione ConnectionId può causare la rappresentazione dannosa se la versione del server o del SignalR client è ASP.NET Core 2.2 o versioni precedenti. Se il server e la SignalR versione client sono ASP.NET Core 3.0 o versione successiva, il ConnectionToken anziché deve ConnectionId essere mantenuto segreto. l'oggetto ConnectionToken non è esposto in alcuna API. Può essere difficile assicurarsi che i client meno recenti SignalR non si connettano al server, quindi anche se la SignalR versione del server è ASP.NET Core 3.0 o versione successiva, l'oggetto ConnectionId non deve essere esposto.

Registrazione dei token di accesso

Quando si usano WebSocket o Eventi inviati dal server, il client del browser invia il token di accesso nella stringa di query. La ricezione del token di accesso tramite la stringa di query è in genere sicura come l'uso dell'intestazione standard Authorization . Usare sempre HTTPS per garantire una connessione end-to-end sicura tra il client e il server. Molti server Web registrano l'URL per ogni richiesta, inclusa la stringa di query. La registrazione degli URL può registrare il token di accesso. ASP.NET Core registra l'URL per ogni richiesta per impostazione predefinita, che include la stringa di query. Ad esempio:

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

In caso di dubbi sulla registrazione di questi dati con i log del server, è possibile disabilitare completamente questa registrazione configurando il Microsoft.AspNetCore.Hosting logger al Warning livello o superiore (questi messaggi vengono scritti a Info livello). Per altre informazioni, vedere Applicare le regole di filtro dei log nel codice . Se si desidera comunque registrare determinate informazioni sulla richiesta, è possibile scrivere middleware per registrare i dati necessari e filtrare il valore della access_token stringa di query (se presente).

Eccezioni

I messaggi di eccezione sono in genere considerati dati sensibili che non devono essere rivelati a un client. Per impostazione predefinita, SignalR non invia i dettagli di un'eccezione generata da un metodo hub al client. Il client riceve invece un messaggio generico che indica che si è verificato un errore. Il recapito dei messaggi di eccezione al client può essere sottoposto a override (ad esempio in fase di sviluppo o test) con EnableDetailedErrors. I messaggi di eccezione non devono essere esposti al client nelle app di produzione.

Gestione del buffer

SignalR usa buffer per connessione per gestire i messaggi in ingresso e in uscita. Per impostazione predefinita, SignalR limita questi buffer a 32 KB. Il messaggio più grande che un client o un server può inviare è 32 KB. La memoria massima utilizzata da una connessione per i messaggi è di 32 KB. Se i messaggi sono sempre inferiori a 32 KB, è possibile ridurre il limite, che:

  • Impedisce a un client di inviare un messaggio più grande.
  • Il server non dovrà mai allocare buffer di grandi dimensioni per accettare messaggi.

Se i messaggi superano i 32 KB, è possibile aumentare il limite. L'aumento di questo limite significa:

  • Il client può causare l'allocazione di buffer di memoria di grandi dimensioni da parte del server.
  • L'allocazione del server di buffer di grandi dimensioni può ridurre il numero di connessioni simultanee.

Esistono limiti per i messaggi in ingresso e in uscita, entrambi possono essere configurati nell'oggetto HttpConnectionDispatcherOptions configurato in MapHub:

  • ApplicationMaxBufferSize rappresenta il numero massimo di byte dal client memorizzato nel buffer del server. Se il client tenta di inviare un messaggio superiore a questo limite, la connessione potrebbe essere chiusa.
  • TransportMaxBufferSize rappresenta il numero massimo di byte che il server può inviare. Se il server tenta di inviare un messaggio (inclusi i valori restituiti dai metodi hub) maggiore di questo limite, verrà generata un'eccezione.

L'impostazione del limite per 0 disabilitare il limite. La rimozione del limite consente a un client di inviare un messaggio di qualsiasi dimensione. I client malintenzionati che inviano messaggi di grandi dimensioni possono causare l'allocazione della memoria in eccesso. L'utilizzo eccessivo della memoria può ridurre significativamente il numero di connessioni simultanee.

Questo articolo fornisce informazioni sulla protezione di SignalR.

Condivisione di risorse tra le origini

La condivisione di risorse tra le origini (CORS) può essere usata per consentire le connessioni tra le origini SignalR nel browser. Se il codice JavaScript è ospitato in un dominio diverso dall'app SignalR , il middleware CORS deve essere abilitato per consentire a JavaScript di connettersi all'app SignalR . Consenti richieste tra le origini solo dai domini attendibili o controllati. Ad esempio:

  • Il sito è ospitato in http://www.example.com
  • L'app SignalR è ospitata in http://signalr.example.com

CORS deve essere configurato nell'app SignalR per consentire solo l'origine www.example.com.

Per altre informazioni sulla configurazione di CORS, vedere Abilitare le richieste tra origini (CORS). SignalRrichiede i criteri CORS seguenti:

  • Consente le origini previste specifiche. È possibile consentire qualsiasi origine, ma non è sicura o consigliata.
  • I metodi GET HTTP e POST devono essere consentiti.
  • Le credenziali devono essere consentite affinché cookiele sessioni permanenti basate su funzionino correttamente. Devono essere abilitati anche quando l'autenticazione non viene usata.

Tuttavia, nella versione 5.0 è stata fornita un'opzione nel client TypeScript per non usare le credenziali. L'opzione per non usare le credenziali deve essere usata solo quando si conosce il 100% che le credenziali come i cookie non sono necessarie nell'app (i cookie vengono usati dal servizio app di Azure quando si usano più server per sessioni permanenti).

Ad esempio, i criteri CORS seguenti consentono a un SignalR client browser ospitato in https://example.com di accedere all'app SignalR ospitata in 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 ...
}

Restrizione dell'origine WebSocket

La protezione fornita da CORS non si applica agli oggetti WebSocket. Per la restrizione dell'origine nei WebSocket, vedere Restrizione dell'origine WebSocket.

La protezione fornita da CORS non si applica agli oggetti WebSocket. I browser non:

  • Eseguono richieste CORS preventive.
  • Rispettano le restrizioni specificate nelle intestazioni Access-Control quando eseguono richieste WebSocket.

I browser, tuttavia, inviano l'intestazione Origin quando rilasciano richieste WebSocket. Le applicazioni devono essere configurate per la convalida di queste intestazioni per assicurarsi che siano consentiti solo WebSocket provenienti dalle origini previste.

In ASP.NET Core 2.1 e versioni successive, è possibile ottenere la convalida dell'intestazione usando un middleware personalizzato posizionato prima UseSignalRdi e il middleware di autenticazione in 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 ...
}

Nota

L'intestazione Origin viene controllata dal client e, come l'intestazione Referer, può essere falsificata. Queste intestazioni non devono essere usate come meccanismo di autenticazione.

ID connessione

L'esposizione ConnectionId può causare la rappresentazione dannosa se la versione del server o del SignalR client è ASP.NET Core 2.2 o versioni precedenti. Se il server e la SignalR versione client sono ASP.NET Core 3.0 o versione successiva, il ConnectionToken anziché deve ConnectionId essere mantenuto segreto. l'oggetto ConnectionToken non è esposto in alcuna API. Può essere difficile assicurarsi che i client meno recenti SignalR non si connettano al server, quindi anche se la SignalR versione del server è ASP.NET Core 3.0 o versione successiva, l'oggetto ConnectionId non deve essere esposto.

Registrazione dei token di accesso

Quando si usano WebSocket o Eventi inviati dal server, il client del browser invia il token di accesso nella stringa di query. La ricezione del token di accesso tramite la stringa di query è in genere sicura come l'uso dell'intestazione standard Authorization . Usare sempre HTTPS per garantire una connessione end-to-end sicura tra il client e il server. Molti server Web registrano l'URL per ogni richiesta, inclusa la stringa di query. La registrazione degli URL può registrare il token di accesso. ASP.NET Core registra l'URL per ogni richiesta per impostazione predefinita, che include la stringa di query. Ad esempio:

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

In caso di dubbi sulla registrazione di questi dati con i log del server, è possibile disabilitare completamente questa registrazione configurando il Microsoft.AspNetCore.Hosting logger al Warning livello o superiore (questi messaggi vengono scritti a Info livello). Per altre informazioni, vedere Applicare le regole di filtro dei log nel codice . Se si desidera comunque registrare determinate informazioni sulla richiesta, è possibile scrivere middleware per registrare i dati necessari e filtrare il valore della access_token stringa di query (se presente).

Eccezioni

I messaggi di eccezione sono in genere considerati dati sensibili che non devono essere rivelati a un client. Per impostazione predefinita, SignalR non invia i dettagli di un'eccezione generata da un metodo hub al client. Il client riceve invece un messaggio generico che indica che si è verificato un errore. Il recapito dei messaggi di eccezione al client può essere sottoposto a override (ad esempio in fase di sviluppo o test) con EnableDetailedErrors. I messaggi di eccezione non devono essere esposti al client nelle app di produzione.

Gestione del buffer

SignalR usa buffer per connessione per gestire i messaggi in ingresso e in uscita. Per impostazione predefinita, SignalR limita questi buffer a 32 KB. Il messaggio più grande che un client o un server può inviare è 32 KB. La memoria massima utilizzata da una connessione per i messaggi è di 32 KB. Se i messaggi sono sempre inferiori a 32 KB, è possibile ridurre il limite, che:

  • Impedisce a un client di inviare un messaggio più grande.
  • Il server non dovrà mai allocare buffer di grandi dimensioni per accettare messaggi.

Se i messaggi superano i 32 KB, è possibile aumentare il limite. L'aumento di questo limite significa:

  • Il client può causare l'allocazione di buffer di memoria di grandi dimensioni da parte del server.
  • L'allocazione del server di buffer di grandi dimensioni può ridurre il numero di connessioni simultanee.

Esistono limiti per i messaggi in ingresso e in uscita, entrambi possono essere configurati nell'oggetto HttpConnectionDispatcherOptions configurato in MapHub:

  • ApplicationMaxBufferSize rappresenta il numero massimo di byte dal client memorizzato nel buffer del server. Se il client tenta di inviare un messaggio superiore a questo limite, la connessione potrebbe essere chiusa.
  • TransportMaxBufferSize rappresenta il numero massimo di byte che il server può inviare. Se il server tenta di inviare un messaggio (inclusi i valori restituiti dai metodi hub) maggiore di questo limite, verrà generata un'eccezione.

L'impostazione del limite per 0 disabilitare il limite. La rimozione del limite consente a un client di inviare un messaggio di qualsiasi dimensione. I client malintenzionati che inviano messaggi di grandi dimensioni possono causare l'allocazione della memoria in eccesso. L'utilizzo eccessivo della memoria può ridurre significativamente il numero di connessioni simultanee.