Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
av Patrick Fletcher, Tom FitzMacken
Varning
Den här dokumentationen gäller inte för den senaste versionen av SignalR. Ta en titt på ASP.NET Core SignalR.
I den här artikeln beskrivs de säkerhetsproblem som du måste tänka på när du utvecklar ett SignalR-program.
Programvaruversioner som används i det här avsnittet
- Visual Studio 2013
- .NET 4.5
- SignalR version 2
Tidigare versioner av det här ämnet
Information om tidigare versioner av SignalR finns i Äldre SignalR-versioner.
Frågor och kommentarer
Lämna gärna feedback om hur du uppskattade den här handledningen och vad vi kan förbättra i kommentarerna längst ned på sidan. Om du har frågor som inte är direkt relaterade till självstudien kan du skicka dem till ASP.NET SignalR-forumet eller StackOverflow.com.
Översikt
Det här dokumentet innehåller följande avsnitt:
SignalR-säkerhetsbegrepp
Autentisering och auktorisering
SignalR tillhandahåller inga funktioner för autentisering av användare. I stället integrerar du SignalR-funktionerna i den befintliga autentiseringsstrukturen för ett program. Du autentiserar användare som vanligt i ditt program och arbetar med resultatet av autentiseringen i SignalR-koden. Du kan till exempel autentisera dina användare med ASP.NET formulärautentisering och sedan framtvinga vilka användare eller roller som har behörighet att anropa en metod i hubben. I din hubb kan du också skicka autentiseringsinformation, till exempel användarnamn eller om en användare tillhör en roll, till klienten.
SignalR tillhandahåller attributet Auktorisera för att ange vilka användare som har åtkomst till en hubb eller metod. Du använder attributet Auktorisera för antingen en hubb eller vissa metoder i en hubb. Utan attributet Auktorisera är alla offentliga metoder på hubben tillgängliga för en klient som är ansluten till hubben. Mer information om hubbar finns i Autentisering och auktorisering för SignalR Hubs.
Du använder Authorize attributet för hubbar, men inte beständiga anslutningar. Om du vill tillämpa auktoriseringsregler när du använder en PersistentConnection måste du åsidosätta AuthorizeRequest metoden. Mer information om beständiga anslutningar finns i Autentisering och auktorisering för Beständiga SignalR-anslutningar.
Anslutningstoken
SignalR minskar risken för att köra skadliga kommandon genom att verifiera avsändarens identitet. För varje begäran skickar klienten och servern en anslutningstoken som innehåller anslutnings-ID och användarnamn för autentiserade användare. Anslutnings-ID:t identifierar unikt varje ansluten klient. Servern genererar slumpmässigt anslutnings-ID:t när en ny anslutning skapas och bevarar det ID:t under anslutningens varaktighet. Autentiseringsmekanismen för webbprogrammet innehåller användarnamnet. SignalR använder kryptering och en digital signatur för att skydda anslutningstoken.
För varje begäran verifierar servern innehållet i token för att säkerställa att begäran kommer från den angivna användaren. Användarnamnet måste motsvara anslutnings-ID:t. Genom att verifiera både anslutnings-ID:t och användarnamnet förhindrar SignalR att en obehörig användare enkelt utger sig för att vara en annan användare. Om servern inte kan verifiera anslutningstoken misslyckas begäran.
Eftersom anslutnings-ID är en del av verifieringsprocessen bör du inte avslöja en användares anslutnings-ID för andra användare eller lagra värdet på klienten, till exempel i en cookie.
Anslutningstoken jämfört med andra tokentyper
Anslutningstoken flaggas ibland av säkerhetsverktyg eftersom de verkar vara sessionstoken eller autentiseringstoken, vilket utgör en risk om de exponeras.
SignalR:s anslutningstoken är inte en autentiseringstoken. Den används för att bekräfta att användaren som gör den här begäran är samma som skapade anslutningen. Anslutningstoken är nödvändig eftersom ASP.NET SignalR tillåter anslutningar att flytta mellan servrar. Token associerar anslutningen med en viss användare men bekräftar inte identiteten för den användare som gör begäran. För att en SignalR-begäran ska autentiseras korrekt måste den ha någon annan token som bekräftar användarens identitet, till exempel en cookie eller ägartoken. Själva anslutningstoken gör dock inget anspråk på att begäran gjordes av användaren, bara att anslutnings-ID:t i token är associerat med den användaren.
Eftersom anslutningstoken inte ger något eget autentiseringsanspråk betraktas den inte som en "session" eller "autentiseringstoken". Det går inte att ta en viss användares anslutningstoken och spela upp den i en begäran som autentiserats som en annan användare (eller en oautentiserad begäran), eftersom användaridentiteten för begäran och identiteten som lagras i token inte matchar.
Återansluta till grupper vid återanslutning
Som standard tilldelar SignalR-programmet automatiskt en användare till lämpliga grupper när de återansluter från ett tillfälligt avbrott, till exempel när en anslutning tas bort och återupprättas innan anslutningen överskrider tidsgränsen. När du återansluter skickar klienten en grupptoken som innehåller anslutnings-ID:t och de tilldelade grupperna. Grupptoken är digitalt signerad och krypterad. Klienten behåller samma anslutnings-ID efter en återanslutning. Därför måste anslutnings-ID:t som skickades från den återanslutna klienten matcha det tidigare anslutnings-ID som användes av klienten. Den här verifieringen hindrar en obehörig användare från att skicka begäranden om att ansluta till obehöriga grupper vid återanslutning.
Det är dock viktigt att notera att grupptoken inte upphör att gälla. Om en användare tidigare tillhörde en grupp, men förbjöds från den gruppen, kanske användaren kan efterlikna en grupptoken som innehåller den förbjudna gruppen. Om du behöver hantera vilka användare som tillhör vilka grupper på ett säkert sätt måste du lagra dessa data på servern, till exempel i en databas. Lägg sedan till logik i ditt program som verifierar på servern om en användare tillhör en grupp. Ett exempel på hur du verifierar gruppmedlemskap finns i Arbeta med grupper.
Automatiskt återanslutna grupper gäller endast när en anslutning återansluts efter ett tillfälligt avbrott. Om en användare kopplar från genom att navigera bort från programmet eller om programmet startas om, måste programmet hantera hur användaren ska läggas till i rätt grupper. Mer information finns i Arbeta med grupper.
Så här förhindrar SignalR förfalskning av begäranden mellan webbplatser
Förfalskning av begäranden mellan webbplatser (CSRF) är ett angrepp där en skadlig webbplats skickar en begäran till en sårbar webbplats där användaren för närvarande är inloggad. SignalR förhindrar CSRF genom att göra det extremt osannolikt för en skadlig webbplats att skapa en giltig begäran för ditt SignalR-program.
Beskrivning av CSRF-attack
Här är ett exempel på en CSRF-attack:
En användare loggar in på
www.example.com, med hjälp av formulärautentisering.Servern autentiserar användaren. Svaret från servern innehåller en autentiseringscookie.
Utan att logga ut besöker användaren en skadlig webbplats. Den här skadliga webbplatsen innehåller följande HTML-formulär:
<h1>You Are a Winner!</h1> <form action="http://example.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click Me"/> </form>Observera att formuläråtgärden skickas till den sårbara webbplatsen, inte till den skadliga webbplatsen. Det här är "cross-site"-delen av CSRF.
Användaren klickar på knappen Skicka. Webbläsaren innehåller autentiseringscookien med begäran.
Begäran körs på example.com-servern med användarens autentiseringskontext och kan göra allt som en autentiserad användare får göra.
Även om det här exemplet kräver att användaren klickar på formulärknappen kan den skadliga sidan lika enkelt köra ett skript som skickar en AJAX-begäran till ditt SignalR-program. Dessutom förhindrar inte användning av SSL en CSRF-attack, eftersom den skadliga webbplatsen kan skicka en "https://"-begäran.
Normalt är CSRF-attacker möjliga mot webbplatser som använder cookies för autentisering, eftersom webbläsare skickar alla relevanta cookies till målwebbplatsen. CSRF-attacker är dock inte begränsade till att utnyttja cookies. Till exempel är grundläggande och sammanfattad autentisering också sårbara. När en användare har loggat in med Basic- eller Digest-autentisering skickar webbläsaren automatiskt autentiseringsuppgifterna tills sessionen är slut.
Åtgärder för att motverka CSRF som genomförs av SignalR
SignalR vidtar följande steg för att förhindra att en skadlig webbplats skapar giltiga begäranden till ditt program. SignalR vidtar dessa steg som standard. Du behöver inte vidta några åtgärder i koden.
- Inaktivera begäranden mellan domäner SignalR inaktiverar begäranden mellan domäner för att förhindra att användare anropar en SignalR-slutpunkt från en extern domän. SignalR anser att alla förfrågningar från en extern domän är ogiltiga och blockerar begäran. Vi rekommenderar att du behåller det här standardbeteendet. Annars kan en skadlig webbplats lura användare att skicka kommandon till din webbplats. Om du behöver använda begäranden mellan domäner kan du läsa Så här upprättar du en anslutning mellan domäner .
- Skicka anslutningstoken i frågesträngen, inte cookien SignalR skickar anslutningstoken som ett frågesträngsvärde i stället för som en cookie. Det är osäkert att lagra anslutningstoken i en cookie eftersom webbläsaren oavsiktligt kan vidarebefordra anslutningstoken när skadlig kod påträffas. Att skicka anslutningstoken i frågesträngen förhindrar också att anslutningstoken bevaras utanför den aktuella anslutningen. Därför kan en obehörig användare inte göra en begäran under en annan användares autentiseringsuppgifter.
- Verifiera anslutningstoken Enligt beskrivningen i avsnittet Anslutningstoken vet servern vilket anslutnings-ID som är associerat med varje autentiserad användare. Servern bearbetar inte någon begäran från ett anslutnings-ID som inte matchar användarnamnet. Det är osannolikt att en obehörig användare kan gissa en giltig begäran eftersom den skadliga användaren måste känna till användarnamnet och det aktuella slumpmässigt genererade anslutnings-ID:t. Anslutnings-ID:t blir ogiltigt så snart anslutningen har avslutats. Anonyma användare bör inte ha åtkomst till känslig information.
SignalR-säkerhetsrekommendationer
SSL-protokoll (Secure Socket Layer)
SSL-protokollet använder kryptering för att skydda dataöverföringen mellan en klient och en server. Om SignalR-programmet överför känslig information mellan klienten och servern använder du SSL för transporten. Mer information om hur du konfigurerar SSL finns i Så här konfigurerar du SSL på IIS 7.
Använd inte grupper som en säkerhetsmekanism
Grupper är ett praktiskt sätt att samla in relaterade användare, men de är inte en säker mekanism för att begränsa åtkomsten till känslig information. Detta gäller särskilt när användare automatiskt kan återansluta grupper under en återanslutning. Överväg i stället att lägga till privilegierade användare i en roll och begränsa åtkomsten till en hubbmetod till endast medlemmar i den rollen. Ett exempel på hur du begränsar åtkomst baserat på en roll finns i Autentisering och auktorisering för SignalR Hubs. Ett exempel på hur du kontrollerar användaråtkomst till grupper vid återanslutning finns i Arbeta med grupper.
Hantera indata från klienter på ett säkert sätt
För att säkerställa att en obehörig användare inte skickar skript till andra användare måste du koda alla indata från klienter som är avsedda för sändning till andra klienter. Du bör koda meddelanden på de mottagande klienterna i stället för servern, eftersom signalR-programmet kan ha många olika typer av klienter. Därför fungerar HTML-kodning för en webbklient, men inte för andra typer av klienter. Till exempel skulle en webbklientmetod för att visa ett chattmeddelande hantera användarnamnet och meddelandet på ett säkert sätt genom att anropa html() funktionen.
chat.client.addMessageToPage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
Avstämning av en ändring i användarstatus med en aktiv anslutning
Om en användares autentiseringsstatus ändras när det finns en aktiv anslutning får användaren ett felmeddelande om att användarens identitet inte kan ändras under en aktiv SignalR-anslutning. I så fall bör programmet återansluta till servern för att se till att anslutnings-ID:t och användarnamnet är koordinerade. Om ditt program till exempel tillåter att användaren loggar ut medan det finns en aktiv anslutning matchar inte längre användarnamnet för anslutningen det namn som skickas för nästa begäran. Du vill stoppa anslutningen innan användaren loggar ut och sedan starta om den.
Observera dock att de flesta program inte behöver stoppa och starta anslutningen manuellt. Om ditt program omdirigerar användare till en separat sida efter utloggning, till exempel standardbeteendet i ett webbformulärprogram eller ett MVC-program, eller uppdaterar den aktuella sidan efter utloggning, kopplas den aktiva anslutningen automatiskt från och kräver ingen ytterligare åtgärd.
I följande exempel visas hur du stoppar och startar en anslutning när användarstatusen har ändrats.
<script type="text/javascript">
$(function () {
var chat = $.connection.sampleHub;
$.connection.hub.start().done(function () {
$('#logoutbutton').click(function () {
chat.connection.stop();
$.ajax({
url: "Services/SampleWebService.svc/LogOut",
type: "POST"
}).done(function () {
chat.connection.start();
});
});
});
});
</script>
Eller så kan användarens autentiseringsstatus ändras om din webbplats använder glidande förfallotid med formulärautentisering och det inte finns någon aktivitet för att hålla autentiseringscookien giltig. I så fall loggas användaren ut och användarnamnet matchar inte längre användarnamnet i anslutningstoken. Du kan åtgärda det här problemet genom att lägga till ett skript som regelbundet begär en resurs på webbservern för att hålla autentiseringscookien giltig. I följande exempel visas hur du begär en resurs var 30:e minut.
$(function () {
setInterval(function() {
$.ajax({
url: "Ping.aspx",
cache: false
});
}, 1800000);
});
Automatiskt genererade JavaScript-proxyfiler
Om du inte vill inkludera alla hubbar och metoder i JavaScript-proxyfilen för varje användare kan du inaktivera den automatiska genereringen av filen. Du kan välja det här alternativet om du har flera hubbar och metoder, men inte vill att alla användare ska känna till alla metoder. Du inaktiverar automatisk generering genom att ange EnableJavaScriptProxies till false.
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableJavaScriptProxies = false;
app.MapSignalR(hubConfiguration);
Mer information om JavaScript-proxyfilerna finns i Den genererade proxyn och vad den gör åt dig.
Undantag
Du bör undvika att skicka undantagsobjekt till klienter eftersom objekten kan exponera känslig information för klienterna. Anropa i stället en metod på klienten som visar relevant felmeddelande.
public Task SampleMethod()
{
try
{
// code that can throw an exception
}
catch(Exception e)
{
// add code to log exception and take remedial steps
return Clients.Caller.DisplayError("Sorry, the request could not be processed.");
}
}