Sicherheitsaspekte in ASP.NET Core SignalR

Von Andrew Stanton-Nurse

Dieser Artikel enthält Informationen zum Absichern von SignalR.

Ursprungsübergreifende Ressourcenfreigabe (Cross-Origin Resource Sharing, CROS)

CORS (Cross-Origin Resource Sharing, Ressourcenfreigabe zwischen verschiedenen Ursprüngen) kann verwendet werden, um ursprungsübergreifende SignalR-Verbindungen im Browser zuzulassen. Wenn JavaScript-Code in einer anderen Domäne als die SignalR-App gehostet wird, muss CORS-Middleware aktiviert werden, damit der JavaScript-Code sich mit der SignalR-App verbinden kann. Lassen Sie ursprungsübergreifende Anforderungen nur aus Domänen zu, denen Sie vertrauen oder die Sie kontrollieren. Beispiel:

  • Ihre Website wird in http://www.example.com gehostet.
  • Ihre SignalR-App wird in http://signalr.example.com gehostet.

CORS muss in der SignalR-App so konfiguriert werden, dass nur der Ursprung www.example.comzugelassen wird.

Weitere Informationen zum Konfigurieren von CORS finden Sie unter Aktivieren von CORS (Cross-Origin Requests). SignalR erfordert die folgenden CORS-Richtlinien:

  • Die spezifischen erwarteten Ursprünge zulassen. Es ist möglich, jeden Ursprung zuzulassen, aber weder sicher noch empfohlen.
  • Die HTTP-Methoden GET und POST müssen zugelassen werden.
  • Anmeldeinformationen müssen zugelassen werden, damit auf cookie basierende Sitzungsaffinität ordnungsgemäß funktioniert. Sie müssen auch dann aktiviert werden, wenn auf Authentifizierung verzichtet wird.

In Version 5.0 haben wir jedoch eine Option im TypeScript-Client bereitgestellt, die es erlaubt, auf Anmeldeinformationen zu verzichten. Die Option zum Verzicht auf Anmeldeinformationen sollte nur gewählt werden, wenn Sie genau wissen, dass Anmeldeinformationen wie Cookies in Ihrer App nicht benötigt werden (cookies werden von Azure App Service bei Verwendung mehrerer Server für Sitzungsaffinität genutzt).

Beispielsweise erlaubt die folgende hervorgehobene CORS-Richtlinie einem SignalR-Browserclient, der in https://example.com gehostet wird, den Zugriff auf die in https://signalr.example.com gehostete SignalR-App:

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");

Im vorherigen Beispiel wird die CORS-Richtlinie so angepasst, dass bestimmte Ursprünge, Methoden und Anmeldeinformationen zulässig sind. Weitere Informationen zum Anpassen von CORS-Richtlinien und Middleware in ASP.NET Core finden Sie unter CORS-Middleware: CORS mit benannten Richtlinien und Middleware.

Ursprungseinschränkung für WebSockets

Der von CORS erzeugte Schutz gilt nicht für WebSockets. Informationen zur Ursprungseinschränkung für WebSockets finden Sie unter Ursprungseinschränkung für WebSockets.

ConnectionId

Das Verfügbarmachen von ConnectionId kann zu einem Identitätswechsel mit schädlichen Folgen führen, wenn die Version des SignalR-Servers oder -Clients höchstens ASP.NET Core 2.2 ist. Wenn die Version des SignalR-Servers und -Clients mindestens ASP.NET Core 3.0 ist, muss ConnectionToken anstelle von ConnectionId geheim gehalten werden. ConnectionToken wird in einer API nicht absichtlich verfügbar gemacht. Es kann schwierig sein, sicherzustellen, dass ältere SignalR-Clients keine Verbindung mit dem Server herstellen. Selbst wenn die Version Ihres SignalR-Servers also mindestens ASP.NET Core 3.0 ist, darf ConnectionId nicht verfügbar gemacht werden.

Protokollierung von Zugriffstoken

Bei Verwendung von WebSockets oder Server-Sent Events sendet der Browserclient das Zugriffstoken in der Abfragezeichenfolge. Das Empfangen des Zugriffstokens über die Abfragezeichenfolge ist im Allgemeinen genauso sicher wie die Verwendung des standardmäßigen Authorization-Headers. Verwenden Sie stets HTTPS, um eine sichere durchgängige Verbindung zwischen Client und Server sicherzustellen. Viele Webserver protokollieren die URL für jede Anforderung, einschließlich Abfragezeichenfolge. Beim Protokollieren der URLs wird möglicherweise das Zugriffstoken protokolliert. ASP.NET Core protokolliert standardmäßig die URL jeder Anforderung, einschließlich Abfragezeichenfolge. Beispiel:

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

Wenn Sie Bedenken gegen die Protokollierung dieser Daten in Ihren Serverprotokollen haben, können Sie diese Protokollierung vollständig deaktivieren. Konfigurieren Sie dazu die Microsoft.AspNetCore.Hosting-Protokollierung mindestens auf Ebene Warning (diese Meldungen werden auf Ebene Info geschrieben). Weitere Informationen finden Sie unter Anwenden von Protokollfilterregeln im Code. Wenn Sie dennoch bestimmte Anforderungsinformationen protokollieren möchten, können Sie Middleware schreiben, die die benötigten Daten protokolliert und den Wert access_token in der Abfragezeichenfolge herausfiltert (sofern vorhanden).

Ausnahmen

Ausnahmemeldungen werden generell als vertrauliche Daten angesehen, die nicht für einen Client offengelegt werden dürfen. Standardmäßig sendet SignalR keine Details einer von einer Hubmethode ausgelösten Ausnahme an den Client. Stattdessen erhält der Client eine generische Nachricht, die angibt, dass ein Fehler aufgetreten ist. Die Übermittlung von Ausnahmemeldungen an den Client kann (z. B. bei der Entwicklung oder Tests) mithilfe von EnableDetailedErrors außer Kraft gesetzt werden. Ausnahmemeldungen dürfen dem Client in Produktions-Apps nicht verfügbar gemacht werden.

Pufferverwaltung

SignalR verwendet verbindungsspezifische Puffer zum Verwalten ein- und ausgehender Nachrichten. Standardmäßig begrenzt SignalR diese Puffer auf 32 KB. Die maximale Größe einer Nachricht, die ein Client oder Server senden kann, ist 32 KB. Der maximale Arbeitsspeicher, den eine Verbindung für Nachrichten beansprucht, beträgt 32 KB. Wenn Ihre Nachrichten stets kleiner als 32 KB sind, können Sie den Grenzwert herabsetzen, was Folgendes ermöglicht:

  • Verhindert, dass ein Client eine größere Nachricht senden kann.
  • Der Server muss demnach keine großen Puffer für das Empfangen von Nachrichten zuteilen.

Wenn Ihre Nachrichten größer als 32 KB sind, können Sie den Grenzwert erhöhen. Das Erhöhen dieses Grenzwerts bedeutet Folgendes:

  • Der Client kann den Server veranlassen, große Arbeitsspeicherpuffer zuzuteilen.
  • Durch Zuteilung großer Puffer durch den Server kann sich die Anzahl gleichzeitiger Verbindungen verringern.

Es gibt Grenzwerte für ein- und ausgehende Nachrichten. Beide können für das HttpConnectionDispatcherOptions-Objekt in MapHub konfiguriert werden:

  • ApplicationMaxBufferSize stellt die maximale Anzahl von Bytes vom Client dar, die der Server puffert. Wenn der Client versucht, eine Nachricht zu senden, die diesen Grenzwert überschreitet, wird die Verbindung möglicherweise geschlossen.
  • TransportMaxBufferSize stellt die maximale Anzahl von Bytes dar, die der Server senden kann. Wenn der Server versucht, eine Nachricht (einschließlich Rückgabewerten von Hubmethoden) zu senden, die diesen Grenzwert überschreitet, wird eine Ausnahme ausgelöst.

Wenn Sie den Grenzwert auf 0 festlegen, wird dieser deaktiviert. Bei Aufheben des Grenzwertes kann ein Client eine Nachricht beliebiger Größe senden. Schädliche Clients, die große Nachrichten senden, können dafür sorgen, dass Arbeitsspeicher übermäßig zugeteilt wird. Eine übermäßige Arbeitsspeicherauslastung kann die Anzahl gleichzeitiger Verbindungen erheblich reduzieren.

Dieser Artikel enthält Informationen zum Absichern von SignalR.

Ursprungsübergreifende Ressourcenfreigabe (Cross-Origin Resource Sharing, CROS)

CORS (Cross-Origin Resource Sharing, Ressourcenfreigabe zwischen verschiedenen Ursprüngen) kann verwendet werden, um ursprungsübergreifende SignalR-Verbindungen im Browser zuzulassen. Wenn JavaScript-Code in einer anderen Domäne als die SignalR-App gehostet wird, muss CORS-Middleware aktiviert werden, damit der JavaScript-Code sich mit der SignalR-App verbinden kann. Lassen Sie ursprungsübergreifende Anforderungen nur aus Domänen zu, denen Sie vertrauen oder die Sie kontrollieren. Beispiel:

  • Ihre Website wird in http://www.example.com gehostet.
  • Ihre SignalR-App wird in http://signalr.example.com gehostet.

CORS muss in der SignalR-App so konfiguriert werden, dass nur der Ursprung www.example.comzugelassen wird.

Weitere Informationen zum Konfigurieren von CORS finden Sie unter Aktivieren von CORS (Cross-Origin Requests). SignalR erfordert die folgenden CORS-Richtlinien:

  • Die spezifischen erwarteten Ursprünge zulassen. Es ist möglich, jeden Ursprung zuzulassen, aber weder sicher noch empfohlen.
  • Die HTTP-Methoden GET und POST müssen zugelassen werden.
  • Anmeldeinformationen müssen zugelassen werden, damit auf cookie basierende Sitzungsaffinität ordnungsgemäß funktioniert. Sie müssen auch dann aktiviert werden, wenn auf Authentifizierung verzichtet wird.

In Version 5.0 haben wir jedoch eine Option im TypeScript-Client bereitgestellt, die es erlaubt, auf Anmeldeinformationen zu verzichten. Die Option zum Verzicht auf Anmeldeinformationen sollte nur gewählt werden, wenn Sie genau wissen, dass Anmeldeinformationen wie Cookies in Ihrer App nicht benötigt werden (cookies werden von Azure App Service bei Verwendung mehrerer Server für Sitzungsaffinität genutzt).

Beispielsweise erlaubt die folgende hervorgehobene CORS-Richtlinie einem SignalR-Browserclient, der in https://example.com gehostet wird, den Zugriff auf die in https://signalr.example.com gehostete SignalR-App:

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");

Im vorherigen Beispiel wird die CORS-Richtlinie so angepasst, dass bestimmte Ursprünge, Methoden und Anmeldeinformationen zulässig sind. Weitere Informationen zum Anpassen von CORS-Richtlinien und Middleware in ASP.NET Core finden Sie unter CORS-Middleware: CORS mit benannten Richtlinien und Middleware.

Ursprungseinschränkung für WebSockets

Der von CORS erzeugte Schutz gilt nicht für WebSockets. Informationen zur Ursprungseinschränkung für WebSockets finden Sie unter Ursprungseinschränkung für WebSockets.

ConnectionId

Das Verfügbarmachen von ConnectionId kann zu einem Identitätswechsel mit schädlichen Folgen führen, wenn die Version des SignalR-Servers oder -Clients höchstens ASP.NET Core 2.2 ist. Wenn die Version des SignalR-Servers und -Clients mindestens ASP.NET Core 3.0 ist, muss ConnectionToken anstelle von ConnectionId geheim gehalten werden. ConnectionToken wird in einer API nicht absichtlich verfügbar gemacht. Es kann schwierig sein, sicherzustellen, dass ältere SignalR-Clients keine Verbindung mit dem Server herstellen. Selbst wenn die Version Ihres SignalR-Servers also mindestens ASP.NET Core 3.0 ist, darf ConnectionId nicht verfügbar gemacht werden.

Protokollierung von Zugriffstoken

Bei Verwendung von WebSockets oder Server-Sent Events sendet der Browserclient das Zugriffstoken in der Abfragezeichenfolge. Das Empfangen des Zugriffstokens über die Abfragezeichenfolge ist im Allgemeinen genauso sicher wie die Verwendung des standardmäßigen Authorization-Headers. Verwenden Sie stets HTTPS, um eine sichere durchgängige Verbindung zwischen Client und Server sicherzustellen. Viele Webserver protokollieren die URL für jede Anforderung, einschließlich Abfragezeichenfolge. Beim Protokollieren der URLs wird möglicherweise das Zugriffstoken protokolliert. ASP.NET Core protokolliert standardmäßig die URL jeder Anforderung, einschließlich Abfragezeichenfolge. Beispiel:

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

Wenn Sie Bedenken gegen die Protokollierung dieser Daten in Ihren Serverprotokollen haben, können Sie diese Protokollierung vollständig deaktivieren. Konfigurieren Sie dazu die Microsoft.AspNetCore.Hosting-Protokollierung mindestens auf Ebene Warning (diese Meldungen werden auf Ebene Info geschrieben). Weitere Informationen finden Sie unter Anwenden von Protokollfilterregeln im Code. Wenn Sie dennoch bestimmte Anforderungsinformationen protokollieren möchten, können Sie Middleware schreiben, die die benötigten Daten protokolliert und den Wert access_token in der Abfragezeichenfolge herausfiltert (sofern vorhanden).

Ausnahmen

Ausnahmemeldungen werden generell als vertrauliche Daten angesehen, die nicht für einen Client offengelegt werden dürfen. Standardmäßig sendet SignalR keine Details einer von einer Hubmethode ausgelösten Ausnahme an den Client. Stattdessen erhält der Client eine generische Nachricht, die angibt, dass ein Fehler aufgetreten ist. Die Übermittlung von Ausnahmemeldungen an den Client kann (z. B. bei der Entwicklung oder Tests) mithilfe von EnableDetailedErrors außer Kraft gesetzt werden. Ausnahmemeldungen dürfen dem Client in Produktions-Apps nicht verfügbar gemacht werden.

Pufferverwaltung

SignalR verwendet verbindungsspezifische Puffer zum Verwalten ein- und ausgehender Nachrichten. Standardmäßig begrenzt SignalR diese Puffer auf 32 KB. Die maximale Größe einer Nachricht, die ein Client oder Server senden kann, ist 32 KB. Der maximale Arbeitsspeicher, den eine Verbindung für Nachrichten beansprucht, beträgt 32 KB. Wenn Ihre Nachrichten stets kleiner als 32 KB sind, können Sie den Grenzwert herabsetzen, was Folgendes ermöglicht:

  • Verhindert, dass ein Client eine größere Nachricht senden kann.
  • Der Server muss demnach keine großen Puffer für das Empfangen von Nachrichten zuteilen.

Wenn Ihre Nachrichten größer als 32 KB sind, können Sie den Grenzwert erhöhen. Das Erhöhen dieses Grenzwerts bedeutet Folgendes:

  • Der Client kann den Server veranlassen, große Arbeitsspeicherpuffer zuzuteilen.
  • Durch Zuteilung großer Puffer durch den Server kann sich die Anzahl gleichzeitiger Verbindungen verringern.

Es gibt Grenzwerte für ein- und ausgehende Nachrichten. Beide können für das HttpConnectionDispatcherOptions-Objekt in MapHub konfiguriert werden:

  • ApplicationMaxBufferSize stellt die maximale Anzahl von Bytes vom Client dar, die der Server puffert. Wenn der Client versucht, eine Nachricht zu senden, die diesen Grenzwert überschreitet, wird die Verbindung möglicherweise geschlossen.
  • TransportMaxBufferSize stellt die maximale Anzahl von Bytes dar, die der Server senden kann. Wenn der Server versucht, eine Nachricht (einschließlich Rückgabewerten von Hubmethoden) zu senden, die diesen Grenzwert überschreitet, wird eine Ausnahme ausgelöst.

Wenn Sie den Grenzwert auf 0 festlegen, wird dieser deaktiviert. Bei Aufheben des Grenzwertes kann ein Client eine Nachricht beliebiger Größe senden. Schädliche Clients, die große Nachrichten senden, können dafür sorgen, dass Arbeitsspeicher übermäßig zugeteilt wird. Eine übermäßige Arbeitsspeicherauslastung kann die Anzahl gleichzeitiger Verbindungen erheblich reduzieren.

Dieser Artikel enthält Informationen zum Absichern von SignalR.

Ursprungsübergreifende Ressourcenfreigabe (Cross-Origin Resource Sharing, CROS)

CORS (Cross-Origin Resource Sharing, Ressourcenfreigabe zwischen verschiedenen Ursprüngen) kann verwendet werden, um ursprungsübergreifende SignalR-Verbindungen im Browser zuzulassen. Wenn JavaScript-Code in einer anderen Domäne als die SignalR-App gehostet wird, muss CORS-Middleware aktiviert werden, damit der JavaScript-Code sich mit der SignalR-App verbinden kann. Lassen Sie ursprungsübergreifende Anforderungen nur aus Domänen zu, denen Sie vertrauen oder die Sie kontrollieren. Beispiel:

  • Ihre Website wird in http://www.example.com gehostet.
  • Ihre SignalR-App wird in http://signalr.example.com gehostet.

CORS muss in der SignalR-App so konfiguriert werden, dass nur der Ursprung www.example.comzugelassen wird.

Weitere Informationen zum Konfigurieren von CORS finden Sie unter Aktivieren von CORS (Cross-Origin Requests). SignalR erfordert die folgenden CORS-Richtlinien:

  • Die spezifischen erwarteten Ursprünge zulassen. Es ist möglich, jeden Ursprung zuzulassen, aber weder sicher noch empfohlen.
  • Die HTTP-Methoden GET und POST müssen zugelassen werden.
  • Anmeldeinformationen müssen zugelassen werden, damit auf cookie basierende Sitzungsaffinität ordnungsgemäß funktioniert. Sie müssen auch dann aktiviert werden, wenn auf Authentifizierung verzichtet wird.

In Version 5.0 haben wir jedoch eine Option im TypeScript-Client bereitgestellt, die es erlaubt, auf Anmeldeinformationen zu verzichten. Die Option zum Verzicht auf Anmeldeinformationen sollte nur gewählt werden, wenn Sie genau wissen, dass Anmeldeinformationen wie Cookies in Ihrer App nicht benötigt werden (cookies werden von Azure App Service bei Verwendung mehrerer Server für Sitzungsaffinität genutzt).

Beispielsweise erlaubt die folgende hervorgehobene CORS-Richtlinie einem SignalR-Browserclient, der in https://example.com gehostet wird, den Zugriff auf die in https://signalr.example.com gehostete SignalR-App:

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");

Im vorherigen Beispiel wird die CORS-Richtlinie so angepasst, dass bestimmte Ursprünge, Methoden und Anmeldeinformationen zulässig sind. Weitere Informationen zum Anpassen von CORS-Richtlinien und Middleware in ASP.NET Core finden Sie unter CORS-Middleware: CORS mit benannten Richtlinien und Middleware.

Ursprungseinschränkung für WebSockets

Der von CORS erzeugte Schutz gilt nicht für WebSockets. Informationen zur Ursprungseinschränkung für WebSockets finden Sie unter Ursprungseinschränkung für WebSockets.

ConnectionId

Das Verfügbarmachen von ConnectionId kann zu einem Identitätswechsel mit schädlichen Folgen führen, wenn die Version des SignalR-Servers oder -Clients höchstens ASP.NET Core 2.2 ist. Wenn die Version des SignalR-Servers und -Clients mindestens ASP.NET Core 3.0 ist, muss ConnectionToken anstelle von ConnectionId geheim gehalten werden. ConnectionToken wird in einer API nicht absichtlich verfügbar gemacht. Es kann schwierig sein, sicherzustellen, dass ältere SignalR-Clients keine Verbindung mit dem Server herstellen. Selbst wenn die Version Ihres SignalR-Servers also mindestens ASP.NET Core 3.0 ist, darf ConnectionId nicht verfügbar gemacht werden.

Protokollierung von Zugriffstoken

Bei Verwendung von WebSockets oder Server-Sent Events sendet der Browserclient das Zugriffstoken in der Abfragezeichenfolge. Das Empfangen des Zugriffstokens über die Abfragezeichenfolge ist im Allgemeinen genauso sicher wie die Verwendung des standardmäßigen Authorization-Headers. Verwenden Sie stets HTTPS, um eine sichere durchgängige Verbindung zwischen Client und Server sicherzustellen. Viele Webserver protokollieren die URL für jede Anforderung, einschließlich Abfragezeichenfolge. Beim Protokollieren der URLs wird möglicherweise das Zugriffstoken protokolliert. ASP.NET Core protokolliert standardmäßig die URL jeder Anforderung, einschließlich Abfragezeichenfolge. Beispiel:

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

Wenn Sie Bedenken gegen die Protokollierung dieser Daten in Ihren Serverprotokollen haben, können Sie diese Protokollierung vollständig deaktivieren. Konfigurieren Sie dazu die Microsoft.AspNetCore.Hosting-Protokollierung mindestens auf Ebene Warning (diese Meldungen werden auf Ebene Info geschrieben). Weitere Informationen finden Sie unter Anwenden von Protokollfilterregeln im Code. Wenn Sie dennoch bestimmte Anforderungsinformationen protokollieren möchten, können Sie Middleware schreiben, die die benötigten Daten protokolliert und den Wert access_token in der Abfragezeichenfolge herausfiltert (sofern vorhanden).

Ausnahmen

Ausnahmemeldungen werden generell als vertrauliche Daten angesehen, die nicht für einen Client offengelegt werden dürfen. Standardmäßig sendet SignalR keine Details einer von einer Hubmethode ausgelösten Ausnahme an den Client. Stattdessen erhält der Client eine generische Nachricht, die angibt, dass ein Fehler aufgetreten ist. Die Übermittlung von Ausnahmemeldungen an den Client kann (z. B. bei der Entwicklung oder Tests) mithilfe von EnableDetailedErrors außer Kraft gesetzt werden. Ausnahmemeldungen dürfen dem Client in Produktions-Apps nicht verfügbar gemacht werden.

Pufferverwaltung

SignalR verwendet verbindungsspezifische Puffer zum Verwalten ein- und ausgehender Nachrichten. Standardmäßig begrenzt SignalR diese Puffer auf 32 KB. Die maximale Größe einer Nachricht, die ein Client oder Server senden kann, ist 32 KB. Der maximale Arbeitsspeicher, den eine Verbindung für Nachrichten beansprucht, beträgt 32 KB. Wenn Ihre Nachrichten stets kleiner als 32 KB sind, können Sie den Grenzwert herabsetzen, was Folgendes ermöglicht:

  • Verhindert, dass ein Client eine größere Nachricht senden kann.
  • Der Server muss demnach keine großen Puffer für das Empfangen von Nachrichten zuteilen.

Wenn Ihre Nachrichten größer als 32 KB sind, können Sie den Grenzwert erhöhen. Das Erhöhen dieses Grenzwerts bedeutet Folgendes:

  • Der Client kann den Server veranlassen, große Arbeitsspeicherpuffer zuzuteilen.
  • Durch Zuteilung großer Puffer durch den Server kann sich die Anzahl gleichzeitiger Verbindungen verringern.

Es gibt Grenzwerte für ein- und ausgehende Nachrichten. Beide können für das HttpConnectionDispatcherOptions-Objekt in MapHub konfiguriert werden:

  • ApplicationMaxBufferSize stellt die maximale Anzahl von Bytes vom Client dar, die der Server puffert. Wenn der Client versucht, eine Nachricht zu senden, die diesen Grenzwert überschreitet, wird die Verbindung möglicherweise geschlossen.
  • TransportMaxBufferSize stellt die maximale Anzahl von Bytes dar, die der Server senden kann. Wenn der Server versucht, eine Nachricht (einschließlich Rückgabewerten von Hubmethoden) zu senden, die diesen Grenzwert überschreitet, wird eine Ausnahme ausgelöst.

Wenn Sie den Grenzwert auf 0 festlegen, wird dieser deaktiviert. Bei Aufheben des Grenzwertes kann ein Client eine Nachricht beliebiger Größe senden. Schädliche Clients, die große Nachrichten senden, können dafür sorgen, dass Arbeitsspeicher übermäßig zugeteilt wird. Eine übermäßige Arbeitsspeicherauslastung kann die Anzahl gleichzeitiger Verbindungen erheblich reduzieren.

Dieser Artikel enthält Informationen zum Absichern von SignalR.

Ursprungsübergreifende Ressourcenfreigabe (Cross-Origin Resource Sharing, CROS)

CORS (Cross-Origin Resource Sharing, Ressourcenfreigabe zwischen verschiedenen Ursprüngen) kann verwendet werden, um ursprungsübergreifende SignalR-Verbindungen im Browser zuzulassen. Wenn JavaScript-Code in einer anderen Domäne als die SignalR-App gehostet wird, muss CORS-Middleware aktiviert werden, damit der JavaScript-Code sich mit der SignalR-App verbinden kann. Lassen Sie ursprungsübergreifende Anforderungen nur aus Domänen zu, denen Sie vertrauen oder die Sie kontrollieren. Beispiel:

  • Ihre Website wird in http://www.example.com gehostet.
  • Ihre SignalR-App wird in http://signalr.example.com gehostet.

CORS muss in der SignalR-App so konfiguriert werden, dass nur der Ursprung www.example.comzugelassen wird.

Weitere Informationen zum Konfigurieren von CORS finden Sie unter Aktivieren von CORS (Cross-Origin Requests). SignalR erfordert die folgenden CORS-Richtlinien:

  • Die spezifischen erwarteten Ursprünge zulassen. Es ist möglich, jeden Ursprung zuzulassen, aber weder sicher noch empfohlen.
  • Die HTTP-Methoden GET und POST müssen zugelassen werden.
  • Anmeldeinformationen müssen zugelassen werden, damit auf cookie basierende Sitzungsaffinität ordnungsgemäß funktioniert. Sie müssen auch dann aktiviert werden, wenn auf Authentifizierung verzichtet wird.

In Version 5.0 haben wir jedoch eine Option im TypeScript-Client bereitgestellt, die es erlaubt, auf Anmeldeinformationen zu verzichten. Die Option zum Verzicht auf Anmeldeinformationen sollte nur gewählt werden, wenn Sie genau wissen, dass Anmeldeinformationen wie Cookies in Ihrer App nicht benötigt werden (cookies werden von Azure App Service bei Verwendung mehrerer Server für Sitzungsaffinität genutzt).

Beispielsweise erlaubt die folgende CORS-Richtlinie einem SignalR-Browserclient, der in https://example.com gehostet wird, den Zugriff auf die in https://signalr.example.com gehostete SignalR-App:

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 ...
}

Ursprungseinschränkung für WebSockets

Der von CORS erzeugte Schutz gilt nicht für WebSockets. Informationen zur Ursprungseinschränkung für WebSockets finden Sie unter Ursprungseinschränkung für WebSockets.

Der von CORS erzeugte Schutz gilt nicht für WebSockets. Für Browser gilt Folgendes nicht:

  • Ausführen von CORS-Preflightanforderungen
  • Berücksichtigen der Einschränkungen, die in den Access-Control-Headern bei der Erstellung von WebSocket-Anforderungen angegeben sind

Allerdings senden Browser den Origin-Header, wenn die WebSocket-Anforderungen ausgegeben werden. Anwendungen sollten zur Überprüfung dieser Header konfiguriert werden, um sicherzustellen, dass nur WebSockets von den erwarteten Ursprüngen zulässig sind.

Ab ASP.NET Core 2.1 kann die Headervalidierung mithilfe einer benutzerdefinierten Middleware, die vor UseSignalR platziert wird, und von Authentifizierungsmiddleware in Configure durchgeführt werden:


// 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 ...
}

Hinweis

Der Origin-Header wird vom Client gesteuert und kann wie der Referer-Header überlistet werden. Diese Header dürfen nicht als Authentifizierungsmechanismus verwendet werden.

ConnectionId

Das Verfügbarmachen von ConnectionId kann zu einem Identitätswechsel mit schädlichen Folgen führen, wenn die Version des SignalR-Servers oder -Clients höchstens ASP.NET Core 2.2 ist. Wenn die Version des SignalR-Servers und -Clients mindestens ASP.NET Core 3.0 ist, muss ConnectionToken anstelle von ConnectionId geheim gehalten werden. ConnectionToken wird in einer API nicht absichtlich verfügbar gemacht. Es kann schwierig sein, sicherzustellen, dass ältere SignalR-Clients keine Verbindung mit dem Server herstellen. Selbst wenn die Version Ihres SignalR-Servers also mindestens ASP.NET Core 3.0 ist, darf ConnectionId nicht verfügbar gemacht werden.

Protokollierung von Zugriffstoken

Bei Verwendung von WebSockets oder Server-Sent Events sendet der Browserclient das Zugriffstoken in der Abfragezeichenfolge. Das Empfangen des Zugriffstokens über die Abfragezeichenfolge ist im Allgemeinen genauso sicher wie die Verwendung des standardmäßigen Authorization-Headers. Verwenden Sie stets HTTPS, um eine sichere durchgängige Verbindung zwischen Client und Server sicherzustellen. Viele Webserver protokollieren die URL für jede Anforderung, einschließlich Abfragezeichenfolge. Beim Protokollieren der URLs wird möglicherweise das Zugriffstoken protokolliert. ASP.NET Core protokolliert standardmäßig die URL jeder Anforderung, einschließlich Abfragezeichenfolge. Beispiel:

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

Wenn Sie Bedenken gegen die Protokollierung dieser Daten in Ihren Serverprotokollen haben, können Sie diese Protokollierung vollständig deaktivieren. Konfigurieren Sie dazu die Microsoft.AspNetCore.Hosting-Protokollierung mindestens auf Ebene Warning (diese Meldungen werden auf Ebene Info geschrieben). Weitere Informationen finden Sie unter Anwenden von Protokollfilterregeln im Code. Wenn Sie dennoch bestimmte Anforderungsinformationen protokollieren möchten, können Sie Middleware schreiben, die die benötigten Daten protokolliert und den Wert access_token in der Abfragezeichenfolge herausfiltert (sofern vorhanden).

Ausnahmen

Ausnahmemeldungen werden generell als vertrauliche Daten angesehen, die nicht für einen Client offengelegt werden dürfen. Standardmäßig sendet SignalR keine Details einer von einer Hubmethode ausgelösten Ausnahme an den Client. Stattdessen erhält der Client eine generische Nachricht, die angibt, dass ein Fehler aufgetreten ist. Die Übermittlung von Ausnahmemeldungen an den Client kann (z. B. bei der Entwicklung oder Tests) mithilfe von EnableDetailedErrors außer Kraft gesetzt werden. Ausnahmemeldungen dürfen dem Client in Produktions-Apps nicht verfügbar gemacht werden.

Pufferverwaltung

SignalR verwendet verbindungsspezifische Puffer zum Verwalten ein- und ausgehender Nachrichten. Standardmäßig begrenzt SignalR diese Puffer auf 32 KB. Die maximale Größe einer Nachricht, die ein Client oder Server senden kann, ist 32 KB. Der maximale Arbeitsspeicher, den eine Verbindung für Nachrichten beansprucht, beträgt 32 KB. Wenn Ihre Nachrichten stets kleiner als 32 KB sind, können Sie den Grenzwert herabsetzen, was Folgendes ermöglicht:

  • Verhindert, dass ein Client eine größere Nachricht senden kann.
  • Der Server muss demnach keine großen Puffer für das Empfangen von Nachrichten zuteilen.

Wenn Ihre Nachrichten größer als 32 KB sind, können Sie den Grenzwert erhöhen. Das Erhöhen dieses Grenzwerts bedeutet Folgendes:

  • Der Client kann den Server veranlassen, große Arbeitsspeicherpuffer zuzuteilen.
  • Durch Zuteilung großer Puffer durch den Server kann sich die Anzahl gleichzeitiger Verbindungen verringern.

Es gibt Grenzwerte für ein- und ausgehende Nachrichten. Beide können für das HttpConnectionDispatcherOptions-Objekt in MapHub konfiguriert werden:

  • ApplicationMaxBufferSize stellt die maximale Anzahl von Bytes vom Client dar, die der Server puffert. Wenn der Client versucht, eine Nachricht zu senden, die diesen Grenzwert überschreitet, wird die Verbindung möglicherweise geschlossen.
  • TransportMaxBufferSize stellt die maximale Anzahl von Bytes dar, die der Server senden kann. Wenn der Server versucht, eine Nachricht (einschließlich Rückgabewerten von Hubmethoden) zu senden, die diesen Grenzwert überschreitet, wird eine Ausnahme ausgelöst.

Wenn Sie den Grenzwert auf 0 festlegen, wird dieser deaktiviert. Bei Aufheben des Grenzwertes kann ein Client eine Nachricht beliebiger Größe senden. Schädliche Clients, die große Nachrichten senden, können dafür sorgen, dass Arbeitsspeicher übermäßig zugeteilt wird. Eine übermäßige Arbeitsspeicherauslastung kann die Anzahl gleichzeitiger Verbindungen erheblich reduzieren.