ASP.NET Core'de güvenlikle ilgili dikkat edilmesi gerekenler SignalR
Andrew Stanton-Nurse tarafından
Bu makalede güvenliğinin sağlanmasıyla ilgili bilgiler SignalR velanmıştır.
Çıkış noktaları arası kaynak paylaşma
Çıkış noktası arası kaynak paylaşımı (CORS), tarayıcıda çıkış noktası arası SignalR bağlantılara izin vermek için kullanılabilir. JavaScript kodu, uygulamadan farklı bir etki alanında barındırıldı ise, JavaScript'in uygulamaya bağlanmasına izin vermek için SignalR CORS ara yazılımı SignalR etkinleştirilmelidir. Çıkış noktası arası isteklere yalnızca güvenen veya denetime sahip etki alanlarından gelen isteklere izin verir. Örnek:
- Siteniz şu sitede barındırıldı:
http://www.example.com - SignalRUygulamanız şu sayfalarda barındırıldı:
http://signalr.example.com
CORS, uygulamada yalnızca SignalR kaynağına izin verecek şekilde www.example.com yapılandırıldı.
CORS'yi yapılandırma hakkında daha fazla bilgi için bkz. Çıkış Noktası Arası İstekleri (CORS) Etkinleştirme. SignalRaşağıdaki CORS ilkelerini gerektirir:
- Beklenen belirli çıkışlara izin verme. Herhangi bir çıkış noktası sağlamak mümkündür ancak güvenli değildir veya önerilmez.
- HTTP yöntemlerine
GETizinPOSTverilmiyor. - Tabanlı yapışkan oturumların düzgün çalışması için cookie kimlik bilgilerine izin verilmiyor. Kimlik doğrulaması kullanılmasa bile etkinleştirilmeleri gerekir.
Ancak, 5.0'da TypeScript istemcisinde kimlik bilgilerini kullanmama seçeneği sağladık. Kimlik bilgilerini kullanmama seçeneği yalnızca uygulamanıza s gibi kimlik bilgilerinin gerekli olmadığını %100 biliyorsanız kullanılmalıdır ( s, yapışkan oturumlar için birden çok sunucu kullanırken Azure App Service tarafından Cookie cookie kullanılır).
Örneğin, aşağıdaki CORS ilkesi üzerinde SignalR barındırılan bir tarayıcı istemcisinin üzerinde https://example.com barındırılan SignalR uygulamaya erişmesini https://signalr.example.com sağlar:
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 ...
}
WebSocket Kaynak Kısıtlaması
CORS tarafından sağlanan korumalar WebSockets için geçerli değildir. WebSockets'de kaynak kısıtlaması için WebSockets kaynak kısıtlaması makalesini okuyun.
CORS tarafından sağlanan korumalar WebSockets için geçerli değildir. Tarayıcılar şunları yapmaz:
- CORS uçuş öncesi istekleri gerçekleştirin.
- WebSocket istekleri
Access-Controlyaparken üst bilgilerde belirtilen kısıtlamalara dikkat edin.
Ancak tarayıcılar Origin WebSocket istekleri gönderirken üst bilgi gönderir. Yalnızca beklenen kaynaklardan gelen WebSocket'lere izin verıldığından emin olmak için uygulamalar bu üst bilgileri doğrular şekilde yapılandırıldı.
2.1 ve sonraki bir ASP.NET Core'de, 'den önce yerleştirilen özel bir ara yazılım ve 'de kimlik doğrulama ara yazılımı kullanılarak UseSignalR üst bilgi doğrulaması elde Configure edilebilir:
// 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 ...
}
Not
Üst Origin bilgi istemci tarafından denetlenerek üst bilgi gibi sahte Referer olabilir. Bu üst bilgiler bir kimlik doğrulama mekanizması olarak kullanılmamalı.
Connectionıd
Sunucu veya istemci ConnectionId sürümü 2.2 veya daha önceki bir sürümde ASP.NET Core neden SignalR olabilir. Sunucu ve istemci sürümü 3.0 ASP.NET Core veya sonraki bir sürüme sahipse, yerine SignalR ConnectionToken gizli ConnectionId tutulmalıdır. ConnectionTokenamacı herhangi bir API'de açıklanmaz. Eski istemcilerin sunucuya bağlanmaması zor olabilir, bu nedenle, sunucu sürümünüz SignalR SignalR 3.0 veya ASP.NET Core olsa bile, bunun açık olmaması ConnectionId gerekir.
Erişim belirteci günlüğü
WebSockets veya Server-Sent kullanırken tarayıcı istemcisi erişim belirteci sorgu dizesinde gönderir. Erişim belirteci sorgu dizesi aracılığıyla almak genellikle standart üst bilgi kullanılarak Authorization güvenlidir. İstemci ile sunucu arasında güvenli bir uz-4 bağlantı sağlamak için her zaman HTTPS kullanın. Birçok web sunucusu, sorgu dizesi de dahil olmak üzere her istek için URL'yi günlüğe alır. URL'ler günlüğe kaydedilirken erişim belirteci günlüğe kaydedilir. ASP.NET Core, sorgu dizesini içerecek her isteğin URL'sini varsayılan olarak günlüğe kaydeder. Örnek:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/chathub?access_token=1234
Bu verileri sunucu günlükleriyle günlüğe kaydetme konusunda endişeleriniz varsa, günlükçleyiciyi düzeye veya üst düzeye yapılandırarak (bu iletiler düzeyinde yazılır) bu günlüğü Microsoft.AspNetCore.Hosting Warning tamamen devre dışı Info abilirsiniz. Daha fazla bilgi için bkz. Kodda günlük filtresi kuralları uygulama. Hala belirli istek bilgilerini günlüğe almak istemiyorsanız, istediğiniz verileri günlüğe almak ve sorgu dizesi değerini (varsa) filtrelemek için bir ara access_token yazılım yazabilirsiniz.
Özel durumlar
Özel durum iletileri genellikle istemciye açık olmaması gereken hassas veriler olarak kabul edilir. Varsayılan SignalR olarak, hub yöntemi tarafından bir özel durumun ayrıntılarını istemciye göndermez. Bunun yerine, istemci bir hatanın meydana geldiğine işaret eden genel bir ileti alır. EnableDetailedErrorsile istemciye özel durum iletisi teslimi geçersiz kılınabilir (örneğin, geliştirme veya testte). Özel durum iletileri, üretim uygulamaları içinde istemciye açık değildir.
Arabellek yönetimi
SignalR gelen ve giden iletileri yönetmek için bağlantı başına arabellekleri kullanır. Varsayılan olarak, SignalR bu arabellekleri 32 KB ile sınırlar. Bir istemcinin veya sunucunun göndere iletiyi en büyük 32 KB'tır. İletiler için bağlantı tarafından tüketilen bellek üst sayısı 32 KB'tır. İletileriniz her zaman 32 KB'den küçükse sınırı azaltabilirsiniz ve bu sınır şu şekildedir:
- bir istemcinin daha büyük bir ileti göndere iletiyi göndermesini önler.
- Sunucunun iletileri kabul etmek için hiçbir zaman büyük arabellekler ayırması gerekmeyen.
İletiniz 32 KB'den büyükse sınırı artırabilirsiniz. Bu sınırın artırılması şu anlama gelir:
- İstemci, sunucunun büyük bellek arabellekleri ayırmasını neden olabilir.
- Büyük arabelleklerin sunucu ayırması, eş zamanlı bağlantı sayısını azaltabilirsiniz.
Gelen ve giden iletiler için sınırlar vardır; her ikisi de içinde yapılandırılan HttpConnectionDispatcherOptions nesnesinde yalıtabilirsiniz: MapHub
ApplicationMaxBufferSize, sunucu tarafından arabelleğe alınan istemciden gelen en fazla bayt sayısını temsil eder. İstemci bu sınırdan daha büyük bir ileti göndermeye çalışırsa bağlantı kapatabilirsiniz.TransportMaxBufferSize, sunucunun gönderebilirsiniz maksimum bayt sayısını temsil eder. Sunucu bu sınırdan daha büyük bir ileti (hub yöntemlerinden dönüş değerleri dahil) göndermeye çalışırsa, bir özel durum oluşturur.
Sınırı olarak ayarlama, 0 sınırı devre dışı bırakır. Sınırın kaldırılması, istemcinin herhangi bir boyutta ileti göndermesini sağlar. Büyük iletiler gönderen kötü amaçlı istemciler fazla belleğin ayrılmış olmasına neden olabilir. Fazla bellek kullanımı eşzamanlı bağlantı sayısını önemli ölçüde azaltabilir.