Udostępnij za pośrednictwem


Zagadnienia dotyczące zabezpieczeń w programie ASP.NET Core SignalR

Przez Andrew Stanton-Nurse

Ten artykuł zawiera informacje na temat zabezpieczania SignalRprogramu .

Współużytkowanie zasobów między źródłami

Udostępnianie zasobów między źródłami (CORS) może służyć do zezwalania na połączenia między źródłami SignalR w przeglądarce. Jeśli kod JavaScript jest hostowany w innej domenie niż SignalR aplikacja, oprogramowanie pośredniczące CORS musi być włączone, aby umożliwić skryptowi JavaScript łączenie się z aplikacjąSignalR. Zezwalaj na żądania między źródłami tylko z domen, którym ufasz lub kontrolujesz. Na przykład:

  • Witryna jest hostowana w witrynie http://www.example.com
  • Aplikacja SignalR jest hostowana w witrynie http://signalr.example.com

Mechanizm CORS należy skonfigurować w aplikacji tak SignalR , aby zezwalał tylko na źródło www.example.com.

Aby uzyskać więcej informacji na temat konfigurowania mechanizmu CORS, zobacz Włączanie żądań między źródłami (CORS). SignalRwymaga następujących zasad CORS:

  • Zezwalaj na określone oczekiwane źródła. Zezwolenie na dowolne źródło jest możliwe, ale nie jest bezpieczne lub zalecane.
  • Metody GET HTTP i POST muszą być dozwolone.
  • Poświadczenia muszą być dozwolone, aby cookiesesje sticky oparte działały poprawnie. Muszą być włączone nawet wtedy, gdy uwierzytelnianie nie jest używane.

Jednak w wersji 5.0 udostępniliśmy opcję w kliencie TypeScript, aby nie używać poświadczeń. Opcja nieużywanych poświadczeń powinna być używana tylko wtedy, gdy wiesz, że 100% poświadczeń, takich jak Cookies, nie są potrzebne w aplikacji (cookiesą używane przez usługę Azure App Service w przypadku korzystania z wielu serwerów na potrzeby sesji sticky).

Na przykład następujące wyróżnione zasady CORS umożliwiają SignalR klientowi przeglądarki hostowanego https://example.com w celu uzyskania dostępu do aplikacji hostowanej SignalR w programie 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");

W poprzednim przykładzie zasady MECHANIZMU CORS są dostosowywane tak, aby zezwalały na określone źródła, metody i poświadczenia. Aby uzyskać więcej informacji na temat dostosowywania zasad CORS i oprogramowania pośredniczącego w programie ASP.NET Core, zobacz oprogramowanie pośredniczące CORS: CORS z nazwanymi zasadami i oprogramowaniem pośredniczącym.

Ograniczenie źródła protokołu WebSocket

Ochrona zapewniana przez mechanizm CORS nie ma zastosowania do obiektów WebSocket. Aby uzyskać ograniczenie pochodzenia dotyczące obiektów WebSocket, przeczytaj artykuł Ograniczenia pochodzenia obiektów WebSocket.

ConnectionId

ConnectionId Ujawnienie może prowadzić do złośliwego personifikacji, jeśli SignalR wersja serwera lub klienta jest ASP.NET Core 2.2 lub starsze. SignalR Jeśli serwer i wersja klienta są ASP.NET Core 3.0 lub nowsze, ConnectionToken zamiast ConnectionId muszą być przechowywane wpisów tajnych. Obiekt ConnectionToken nie jest celowo uwidaczniony w żadnym interfejsie API. Może być trudno upewnić się, że starsi SignalR klienci nie łączą się z serwerem, więc nawet jeśli SignalR wersja serwera jest ASP.NET Core 3.0 lub nowsza, ConnectionId nie powinno być uwidocznione.

Rejestrowanie tokenu dostępu

W przypadku korzystania z obiektów WebSocket lub zdarzeń wysłanych przez serwer klient przeglądarki wysyła token dostępu w ciągu zapytania. Odbieranie tokenu dostępu za pośrednictwem ciągu zapytania jest ogólnie tak bezpieczne, jak w przypadku korzystania ze standardowego Authorization nagłówka. Zawsze używaj protokołu HTTPS, aby zapewnić bezpieczne kompleksowe połączenie między klientem a serwerem. Wiele serwerów internetowych rejestruje adres URL każdego żądania, w tym ciąg zapytania. Rejestrowanie adresów URL może rejestrować token dostępu. ASP.NET Core domyślnie rejestruje adres URL każdego żądania, który zawiera ciąg zapytania. Na przykład:

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

Jeśli masz obawy dotyczące rejestrowania tych danych przy użyciu dzienników serwera, możesz całkowicie wyłączyć to rejestrowanie, konfigurując Microsoft.AspNetCore.Hosting rejestrator na Warning poziomie lub wyższym (te komunikaty są zapisywane na Info poziomie). Aby uzyskać więcej informacji, zobacz Stosowanie reguł filtru dziennika w kodzie , aby uzyskać więcej informacji. Jeśli nadal chcesz rejestrować określone informacje o żądaniu, możesz napisać oprogramowanie pośredniczące, aby zarejestrować wymagane dane i odfiltrować access_token wartość ciągu zapytania (jeśli istnieje).

Wyjątki

Komunikaty o wyjątkach są zwykle uznawane za poufne dane, które nie powinny być ujawniane klientowi. Domyślnie SignalR do klienta nie są wysyłane szczegóły wyjątku zgłaszanego przez metodę centrum. Zamiast tego klient otrzymuje ogólny komunikat wskazujący, że wystąpił błąd. Dostarczanie komunikatów o wyjątku do klienta może zostać zastąpione (na przykład w przypadku programowania lub testowania) za pomocą polecenia EnableDetailedErrors. Komunikaty o wyjątkach nie powinny być widoczne dla klienta w aplikacjach produkcyjnych.

Zarządzanie buforem

SignalR używa buforów dla połączenia do zarządzania przychodzącymi i wychodzącymi komunikatami. Domyślnie SignalR ogranicza te bufory do 32 KB. Największy komunikat, który klient lub serwer może wysłać, to 32 KB. Maksymalna ilość pamięci używanej przez połączenie dla komunikatów wynosi 32 KB. Jeśli komunikaty są zawsze mniejsze niż 32 KB, możesz zmniejszyć limit, który:

  • Uniemożliwia klientowi wysyłanie większego komunikatu.
  • Serwer nigdy nie będzie musiał przydzielać dużych buforów do akceptowania komunikatów.

Jeśli komunikaty są większe niż 32 KB, możesz zwiększyć limit. Zwiększenie tego limitu oznacza:

  • Klient może spowodować przydzielenie dużych buforów pamięci przez serwer.
  • Alokacja serwera dużych buforów może zmniejszyć liczbę połączeń współbieżnych.

Istnieją limity dla komunikatów przychodzących i wychodzących. Oba można skonfigurować w obiekcie Http Połączenie ionDispatcherOptions skonfigurowanym w MapHubpliku :

  • ApplicationMaxBufferSize reprezentuje maksymalną liczbę bajtów od klienta buforowania serwera. Jeśli klient próbuje wysłać komunikat większy niż ten limit, połączenie może zostać zamknięte.
  • TransportMaxBufferSize reprezentuje maksymalną liczbę bajtów, które serwer może wysłać. Jeśli serwer spróbuje wysłać komunikat (w tym wartości zwracane z metod koncentratora) większy niż ten limit, zostanie zgłoszony wyjątek.

Ustawienie limitu 0 wyłącza limit. Usunięcie limitu umożliwia klientowi wysyłanie komunikatu o dowolnym rozmiarze. Złośliwi klienci wysyłający duże komunikaty mogą spowodować przydzielenie nadmiaru pamięci. Nadmiar użycia pamięci może znacznie zmniejszyć liczbę połączeń współbieżnych.

Ten artykuł zawiera informacje na temat zabezpieczania SignalRprogramu .

Współużytkowanie zasobów między źródłami

Udostępnianie zasobów między źródłami (CORS) może służyć do zezwalania na połączenia między źródłami SignalR w przeglądarce. Jeśli kod JavaScript jest hostowany w innej domenie niż SignalR aplikacja, oprogramowanie pośredniczące CORS musi być włączone, aby umożliwić skryptowi JavaScript łączenie się z aplikacjąSignalR. Zezwalaj na żądania między źródłami tylko z domen, którym ufasz lub kontrolujesz. Na przykład:

  • Witryna jest hostowana w witrynie http://www.example.com
  • Aplikacja SignalR jest hostowana w witrynie http://signalr.example.com

Mechanizm CORS należy skonfigurować w aplikacji tak SignalR , aby zezwalał tylko na źródło www.example.com.

Aby uzyskać więcej informacji na temat konfigurowania mechanizmu CORS, zobacz Włączanie żądań między źródłami (CORS). SignalRwymaga następujących zasad CORS:

  • Zezwalaj na określone oczekiwane źródła. Zezwolenie na dowolne źródło jest możliwe, ale nie jest bezpieczne lub zalecane.
  • Metody GET HTTP i POST muszą być dozwolone.
  • Poświadczenia muszą być dozwolone, aby cookiesesje sticky oparte działały poprawnie. Muszą być włączone nawet wtedy, gdy uwierzytelnianie nie jest używane.

Jednak w wersji 5.0 udostępniliśmy opcję w kliencie TypeScript, aby nie używać poświadczeń. Opcja nieużywanych poświadczeń powinna być używana tylko wtedy, gdy wiesz, że 100% poświadczeń, takich jak Cookies, nie są potrzebne w aplikacji (cookiesą używane przez usługę Azure App Service w przypadku korzystania z wielu serwerów na potrzeby sesji sticky).

Na przykład następujące wyróżnione zasady CORS umożliwiają SignalR klientowi przeglądarki hostowanego https://example.com w celu uzyskania dostępu do aplikacji hostowanej SignalR w programie 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");

W poprzednim przykładzie zasady MECHANIZMU CORS są dostosowywane tak, aby zezwalały na określone źródła, metody i poświadczenia. Aby uzyskać więcej informacji na temat dostosowywania zasad CORS i oprogramowania pośredniczącego w programie ASP.NET Core, zobacz oprogramowanie pośredniczące CORS: CORS z nazwanymi zasadami i oprogramowaniem pośredniczącym.

Ograniczenie źródła protokołu WebSocket

Ochrona zapewniana przez mechanizm CORS nie ma zastosowania do obiektów WebSocket. Aby uzyskać ograniczenie pochodzenia dotyczące obiektów WebSocket, przeczytaj artykuł Ograniczenia pochodzenia obiektów WebSocket.

ConnectionId

ConnectionId Ujawnienie może prowadzić do złośliwego personifikacji, jeśli SignalR wersja serwera lub klienta jest ASP.NET Core 2.2 lub starsze. SignalR Jeśli serwer i wersja klienta są ASP.NET Core 3.0 lub nowsze, ConnectionToken zamiast ConnectionId muszą być przechowywane wpisów tajnych. Obiekt ConnectionToken nie jest celowo uwidaczniony w żadnym interfejsie API. Może być trudno upewnić się, że starsi SignalR klienci nie łączą się z serwerem, więc nawet jeśli SignalR wersja serwera jest ASP.NET Core 3.0 lub nowsza, ConnectionId nie powinno być uwidocznione.

Rejestrowanie tokenu dostępu

W przypadku korzystania z obiektów WebSocket lub zdarzeń wysłanych przez serwer klient przeglądarki wysyła token dostępu w ciągu zapytania. Odbieranie tokenu dostępu za pośrednictwem ciągu zapytania jest ogólnie tak bezpieczne, jak w przypadku korzystania ze standardowego Authorization nagłówka. Zawsze używaj protokołu HTTPS, aby zapewnić bezpieczne kompleksowe połączenie między klientem a serwerem. Wiele serwerów internetowych rejestruje adres URL każdego żądania, w tym ciąg zapytania. Rejestrowanie adresów URL może rejestrować token dostępu. ASP.NET Core domyślnie rejestruje adres URL każdego żądania, który zawiera ciąg zapytania. Na przykład:

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

Jeśli masz obawy dotyczące rejestrowania tych danych przy użyciu dzienników serwera, możesz całkowicie wyłączyć to rejestrowanie, konfigurując Microsoft.AspNetCore.Hosting rejestrator na Warning poziomie lub wyższym (te komunikaty są zapisywane na Info poziomie). Aby uzyskać więcej informacji, zobacz Stosowanie reguł filtru dziennika w kodzie , aby uzyskać więcej informacji. Jeśli nadal chcesz rejestrować określone informacje o żądaniu, możesz napisać oprogramowanie pośredniczące, aby zarejestrować wymagane dane i odfiltrować access_token wartość ciągu zapytania (jeśli istnieje).

Wyjątki

Komunikaty o wyjątkach są zwykle uznawane za poufne dane, które nie powinny być ujawniane klientowi. Domyślnie SignalR do klienta nie są wysyłane szczegóły wyjątku zgłaszanego przez metodę centrum. Zamiast tego klient otrzymuje ogólny komunikat wskazujący, że wystąpił błąd. Dostarczanie komunikatów o wyjątku do klienta może zostać zastąpione (na przykład w przypadku programowania lub testowania) za pomocą polecenia EnableDetailedErrors. Komunikaty o wyjątkach nie powinny być widoczne dla klienta w aplikacjach produkcyjnych.

Zarządzanie buforem

SignalR używa buforów dla połączenia do zarządzania przychodzącymi i wychodzącymi komunikatami. Domyślnie SignalR ogranicza te bufory do 32 KB. Największy komunikat, który klient lub serwer może wysłać, to 32 KB. Maksymalna ilość pamięci używanej przez połączenie dla komunikatów wynosi 32 KB. Jeśli komunikaty są zawsze mniejsze niż 32 KB, możesz zmniejszyć limit, który:

  • Uniemożliwia klientowi wysyłanie większego komunikatu.
  • Serwer nigdy nie będzie musiał przydzielać dużych buforów do akceptowania komunikatów.

Jeśli komunikaty są większe niż 32 KB, możesz zwiększyć limit. Zwiększenie tego limitu oznacza:

  • Klient może spowodować przydzielenie dużych buforów pamięci przez serwer.
  • Alokacja serwera dużych buforów może zmniejszyć liczbę połączeń współbieżnych.

Istnieją limity dla komunikatów przychodzących i wychodzących. Oba można skonfigurować w obiekcie Http Połączenie ionDispatcherOptions skonfigurowanym w MapHubpliku :

  • ApplicationMaxBufferSize reprezentuje maksymalną liczbę bajtów od klienta buforowania serwera. Jeśli klient próbuje wysłać komunikat większy niż ten limit, połączenie może zostać zamknięte.
  • TransportMaxBufferSize reprezentuje maksymalną liczbę bajtów, które serwer może wysłać. Jeśli serwer spróbuje wysłać komunikat (w tym wartości zwracane z metod koncentratora) większy niż ten limit, zostanie zgłoszony wyjątek.

Ustawienie limitu 0 wyłącza limit. Usunięcie limitu umożliwia klientowi wysyłanie komunikatu o dowolnym rozmiarze. Złośliwi klienci wysyłający duże komunikaty mogą spowodować przydzielenie nadmiaru pamięci. Nadmiar użycia pamięci może znacznie zmniejszyć liczbę połączeń współbieżnych.

Ten artykuł zawiera informacje na temat zabezpieczania SignalRprogramu .

Współużytkowanie zasobów między źródłami

Udostępnianie zasobów między źródłami (CORS) może służyć do zezwalania na połączenia między źródłami SignalR w przeglądarce. Jeśli kod JavaScript jest hostowany w innej domenie niż SignalR aplikacja, oprogramowanie pośredniczące CORS musi być włączone, aby umożliwić skryptowi JavaScript łączenie się z aplikacjąSignalR. Zezwalaj na żądania między źródłami tylko z domen, którym ufasz lub kontrolujesz. Na przykład:

  • Witryna jest hostowana w witrynie http://www.example.com
  • Aplikacja SignalR jest hostowana w witrynie http://signalr.example.com

Mechanizm CORS należy skonfigurować w aplikacji tak SignalR , aby zezwalał tylko na źródło www.example.com.

Aby uzyskać więcej informacji na temat konfigurowania mechanizmu CORS, zobacz Włączanie żądań między źródłami (CORS). SignalRwymaga następujących zasad CORS:

  • Zezwalaj na określone oczekiwane źródła. Zezwolenie na dowolne źródło jest możliwe, ale nie jest bezpieczne lub zalecane.
  • Metody GET HTTP i POST muszą być dozwolone.
  • Poświadczenia muszą być dozwolone, aby cookiesesje sticky oparte działały poprawnie. Muszą być włączone nawet wtedy, gdy uwierzytelnianie nie jest używane.

Jednak w wersji 5.0 udostępniliśmy opcję w kliencie TypeScript, aby nie używać poświadczeń. Opcja nieużywanych poświadczeń powinna być używana tylko wtedy, gdy wiesz, że 100% poświadczeń, takich jak Cookies, nie są potrzebne w aplikacji (cookiesą używane przez usługę Azure App Service w przypadku korzystania z wielu serwerów na potrzeby sesji sticky).

Na przykład następujące wyróżnione zasady CORS umożliwiają SignalR klientowi przeglądarki hostowanego https://example.com w celu uzyskania dostępu do aplikacji hostowanej SignalR w programie 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");

W poprzednim przykładzie zasady MECHANIZMU CORS są dostosowywane tak, aby zezwalały na określone źródła, metody i poświadczenia. Aby uzyskać więcej informacji na temat dostosowywania zasad CORS i oprogramowania pośredniczącego w programie ASP.NET Core, zobacz oprogramowanie pośredniczące CORS: CORS z nazwanymi zasadami i oprogramowaniem pośredniczącym.

Ograniczenie źródła protokołu WebSocket

Ochrona zapewniana przez mechanizm CORS nie ma zastosowania do obiektów WebSocket. Aby uzyskać ograniczenie pochodzenia dotyczące obiektów WebSocket, przeczytaj artykuł Ograniczenia pochodzenia obiektów WebSocket.

ConnectionId

ConnectionId Ujawnienie może prowadzić do złośliwego personifikacji, jeśli SignalR wersja serwera lub klienta jest ASP.NET Core 2.2 lub starsze. SignalR Jeśli serwer i wersja klienta są ASP.NET Core 3.0 lub nowsze, ConnectionToken zamiast ConnectionId muszą być przechowywane wpisów tajnych. Obiekt ConnectionToken nie jest celowo uwidaczniony w żadnym interfejsie API. Może być trudno upewnić się, że starsi SignalR klienci nie łączą się z serwerem, więc nawet jeśli SignalR wersja serwera jest ASP.NET Core 3.0 lub nowsza, ConnectionId nie powinno być uwidocznione.

Rejestrowanie tokenu dostępu

W przypadku korzystania z obiektów WebSocket lub zdarzeń wysłanych przez serwer klient przeglądarki wysyła token dostępu w ciągu zapytania. Odbieranie tokenu dostępu za pośrednictwem ciągu zapytania jest ogólnie tak bezpieczne, jak w przypadku korzystania ze standardowego Authorization nagłówka. Zawsze używaj protokołu HTTPS, aby zapewnić bezpieczne kompleksowe połączenie między klientem a serwerem. Wiele serwerów internetowych rejestruje adres URL każdego żądania, w tym ciąg zapytania. Rejestrowanie adresów URL może rejestrować token dostępu. ASP.NET Core domyślnie rejestruje adres URL każdego żądania, który zawiera ciąg zapytania. Na przykład:

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

Jeśli masz obawy dotyczące rejestrowania tych danych przy użyciu dzienników serwera, możesz całkowicie wyłączyć to rejestrowanie, konfigurując Microsoft.AspNetCore.Hosting rejestrator na Warning poziomie lub wyższym (te komunikaty są zapisywane na Info poziomie). Aby uzyskać więcej informacji, zobacz Stosowanie reguł filtru dziennika w kodzie , aby uzyskać więcej informacji. Jeśli nadal chcesz rejestrować określone informacje o żądaniu, możesz napisać oprogramowanie pośredniczące, aby zarejestrować wymagane dane i odfiltrować access_token wartość ciągu zapytania (jeśli istnieje).

Wyjątki

Komunikaty o wyjątkach są zwykle uznawane za poufne dane, które nie powinny być ujawniane klientowi. Domyślnie SignalR do klienta nie są wysyłane szczegóły wyjątku zgłaszanego przez metodę centrum. Zamiast tego klient otrzymuje ogólny komunikat wskazujący, że wystąpił błąd. Dostarczanie komunikatów o wyjątku do klienta może zostać zastąpione (na przykład w przypadku programowania lub testowania) za pomocą polecenia EnableDetailedErrors. Komunikaty o wyjątkach nie powinny być widoczne dla klienta w aplikacjach produkcyjnych.

Zarządzanie buforem

SignalR używa buforów dla połączenia do zarządzania przychodzącymi i wychodzącymi komunikatami. Domyślnie SignalR ogranicza te bufory do 32 KB. Największy komunikat, który klient lub serwer może wysłać, to 32 KB. Maksymalna ilość pamięci używanej przez połączenie dla komunikatów wynosi 32 KB. Jeśli komunikaty są zawsze mniejsze niż 32 KB, możesz zmniejszyć limit, który:

  • Uniemożliwia klientowi wysyłanie większego komunikatu.
  • Serwer nigdy nie będzie musiał przydzielać dużych buforów do akceptowania komunikatów.

Jeśli komunikaty są większe niż 32 KB, możesz zwiększyć limit. Zwiększenie tego limitu oznacza:

  • Klient może spowodować przydzielenie dużych buforów pamięci przez serwer.
  • Alokacja serwera dużych buforów może zmniejszyć liczbę połączeń współbieżnych.

Istnieją limity dla komunikatów przychodzących i wychodzących. Oba można skonfigurować w obiekcie Http Połączenie ionDispatcherOptions skonfigurowanym w MapHubpliku :

  • ApplicationMaxBufferSize reprezentuje maksymalną liczbę bajtów od klienta buforowania serwera. Jeśli klient próbuje wysłać komunikat większy niż ten limit, połączenie może zostać zamknięte.
  • TransportMaxBufferSize reprezentuje maksymalną liczbę bajtów, które serwer może wysłać. Jeśli serwer spróbuje wysłać komunikat (w tym wartości zwracane z metod koncentratora) większy niż ten limit, zostanie zgłoszony wyjątek.

Ustawienie limitu 0 wyłącza limit. Usunięcie limitu umożliwia klientowi wysyłanie komunikatu o dowolnym rozmiarze. Złośliwi klienci wysyłający duże komunikaty mogą spowodować przydzielenie nadmiaru pamięci. Nadmiar użycia pamięci może znacznie zmniejszyć liczbę połączeń współbieżnych.

Ten artykuł zawiera informacje na temat zabezpieczania SignalRprogramu .

Współużytkowanie zasobów między źródłami

Udostępnianie zasobów między źródłami (CORS) może służyć do zezwalania na połączenia między źródłami SignalR w przeglądarce. Jeśli kod JavaScript jest hostowany w innej domenie niż SignalR aplikacja, oprogramowanie pośredniczące CORS musi być włączone, aby umożliwić skryptowi JavaScript łączenie się z aplikacjąSignalR. Zezwalaj na żądania między źródłami tylko z domen, którym ufasz lub kontrolujesz. Na przykład:

  • Witryna jest hostowana w witrynie http://www.example.com
  • Aplikacja SignalR jest hostowana w witrynie http://signalr.example.com

Mechanizm CORS należy skonfigurować w aplikacji tak SignalR , aby zezwalał tylko na źródło www.example.com.

Aby uzyskać więcej informacji na temat konfigurowania mechanizmu CORS, zobacz Włączanie żądań między źródłami (CORS). SignalRwymaga następujących zasad CORS:

  • Zezwalaj na określone oczekiwane źródła. Zezwolenie na dowolne źródło jest możliwe, ale nie jest bezpieczne lub zalecane.
  • Metody GET HTTP i POST muszą być dozwolone.
  • Poświadczenia muszą być dozwolone, aby cookiesesje sticky oparte działały poprawnie. Muszą być włączone nawet wtedy, gdy uwierzytelnianie nie jest używane.

Jednak w wersji 5.0 udostępniliśmy opcję w kliencie TypeScript, aby nie używać poświadczeń. Opcja nieużywanych poświadczeń powinna być używana tylko wtedy, gdy wiesz, że 100% poświadczeń, takich jak Cookies, nie są potrzebne w aplikacji (cookiesą używane przez usługę Azure App Service w przypadku korzystania z wielu serwerów na potrzeby sesji sticky).

Na przykład następujące zasady CORS umożliwiają klientowi przeglądarki hostowanego SignalRhttps://example.com na serwerze dostęp do aplikacji hostowanej SignalR w programie 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 ...
}

Ograniczenie źródła protokołu WebSocket

Ochrona zapewniana przez mechanizm CORS nie ma zastosowania do obiektów WebSocket. Aby uzyskać ograniczenie pochodzenia dotyczące obiektów WebSocket, przeczytaj artykuł Ograniczenia pochodzenia obiektów WebSocket.

Ochrona zapewniana przez mechanizm CORS nie ma zastosowania do obiektów WebSocket. Przeglądarki nie:

  • Wykonywanie żądań przed lotem CORS.
  • Przestrzegaj ograniczeń określonych w Access-Control nagłówkach podczas wprowadzania żądań protokołu WebSocket.

Jednak przeglądarki wysyłają nagłówek podczas wysyłania Origin żądań protokołu WebSocket. Aplikacje powinny być skonfigurowane do sprawdzania poprawności tych nagłówków, aby upewnić się, że dozwolone są tylko obiekty WebSocket pochodzące z oczekiwanych źródeł.

W programie ASP.NET Core 2.1 lub nowszym można przeprowadzić walidację nagłówka przy użyciu niestandardowego oprogramowania pośredniczącego umieszczonego przed UseSignalRoprogramowaniem pośredniczącym i uwierzytelniania w programie 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 ...
}

Uwaga

Nagłówek Origin jest kontrolowany przez klienta i, podobnie jak Referer nagłówek, może być fałszywy. Te nagłówki nie powinny być używane jako mechanizm uwierzytelniania.

ConnectionId

ConnectionId Ujawnienie może prowadzić do złośliwego personifikacji, jeśli SignalR wersja serwera lub klienta jest ASP.NET Core 2.2 lub starsze. SignalR Jeśli serwer i wersja klienta są ASP.NET Core 3.0 lub nowsze, ConnectionToken zamiast ConnectionId muszą być przechowywane wpisów tajnych. Obiekt ConnectionToken nie jest celowo uwidaczniony w żadnym interfejsie API. Może być trudno upewnić się, że starsi SignalR klienci nie łączą się z serwerem, więc nawet jeśli SignalR wersja serwera jest ASP.NET Core 3.0 lub nowsza, ConnectionId nie powinno być uwidocznione.

Rejestrowanie tokenu dostępu

W przypadku korzystania z obiektów WebSocket lub zdarzeń wysłanych przez serwer klient przeglądarki wysyła token dostępu w ciągu zapytania. Odbieranie tokenu dostępu za pośrednictwem ciągu zapytania jest ogólnie tak bezpieczne, jak w przypadku korzystania ze standardowego Authorization nagłówka. Zawsze używaj protokołu HTTPS, aby zapewnić bezpieczne kompleksowe połączenie między klientem a serwerem. Wiele serwerów internetowych rejestruje adres URL każdego żądania, w tym ciąg zapytania. Rejestrowanie adresów URL może rejestrować token dostępu. ASP.NET Core domyślnie rejestruje adres URL każdego żądania, który zawiera ciąg zapytania. Na przykład:

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

Jeśli masz obawy dotyczące rejestrowania tych danych przy użyciu dzienników serwera, możesz całkowicie wyłączyć to rejestrowanie, konfigurując Microsoft.AspNetCore.Hosting rejestrator na Warning poziomie lub wyższym (te komunikaty są zapisywane na Info poziomie). Aby uzyskać więcej informacji, zobacz Stosowanie reguł filtru dziennika w kodzie , aby uzyskać więcej informacji. Jeśli nadal chcesz rejestrować określone informacje o żądaniu, możesz napisać oprogramowanie pośredniczące, aby zarejestrować wymagane dane i odfiltrować access_token wartość ciągu zapytania (jeśli istnieje).

Wyjątki

Komunikaty o wyjątkach są zwykle uznawane za poufne dane, które nie powinny być ujawniane klientowi. Domyślnie SignalR do klienta nie są wysyłane szczegóły wyjątku zgłaszanego przez metodę centrum. Zamiast tego klient otrzymuje ogólny komunikat wskazujący, że wystąpił błąd. Dostarczanie komunikatów o wyjątku do klienta może zostać zastąpione (na przykład w przypadku programowania lub testowania) za pomocą polecenia EnableDetailedErrors. Komunikaty o wyjątkach nie powinny być widoczne dla klienta w aplikacjach produkcyjnych.

Zarządzanie buforem

SignalR używa buforów dla połączenia do zarządzania przychodzącymi i wychodzącymi komunikatami. Domyślnie SignalR ogranicza te bufory do 32 KB. Największy komunikat, który klient lub serwer może wysłać, to 32 KB. Maksymalna ilość pamięci używanej przez połączenie dla komunikatów wynosi 32 KB. Jeśli komunikaty są zawsze mniejsze niż 32 KB, możesz zmniejszyć limit, który:

  • Uniemożliwia klientowi wysyłanie większego komunikatu.
  • Serwer nigdy nie będzie musiał przydzielać dużych buforów do akceptowania komunikatów.

Jeśli komunikaty są większe niż 32 KB, możesz zwiększyć limit. Zwiększenie tego limitu oznacza:

  • Klient może spowodować przydzielenie dużych buforów pamięci przez serwer.
  • Alokacja serwera dużych buforów może zmniejszyć liczbę połączeń współbieżnych.

Istnieją limity dla komunikatów przychodzących i wychodzących. Oba można skonfigurować w obiekcie Http Połączenie ionDispatcherOptions skonfigurowanym w MapHubpliku :

  • ApplicationMaxBufferSize reprezentuje maksymalną liczbę bajtów od klienta buforowania serwera. Jeśli klient próbuje wysłać komunikat większy niż ten limit, połączenie może zostać zamknięte.
  • TransportMaxBufferSize reprezentuje maksymalną liczbę bajtów, które serwer może wysłać. Jeśli serwer spróbuje wysłać komunikat (w tym wartości zwracane z metod koncentratora) większy niż ten limit, zostanie zgłoszony wyjątek.

Ustawienie limitu 0 wyłącza limit. Usunięcie limitu umożliwia klientowi wysyłanie komunikatu o dowolnym rozmiarze. Złośliwi klienci wysyłający duże komunikaty mogą spowodować przydzielenie nadmiaru pamięci. Nadmiar użycia pamięci może znacznie zmniejszyć liczbę połączeń współbieżnych.