Sdílet prostřednictvím


Úvod do zabezpečení knihovnou SignalR (SignalR 1.x)

Patrick Fletcher, Tom FitzMacken

Upozornění

Tato dokumentace není určená pro nejnovější verzi služby SignalR. Podívejte se na ASP.NET Core SignalR.

Tento článek popisuje problémy se zabezpečením, které je potřeba vzít v úvahu při vývoji aplikace SignalR.

Přehled

Tento dokument obsahuje následující části:

Koncepty zabezpečení služby SignalR

Ověřování a autorizace

Služba SignalR je navržená tak, aby byla integrovaná do stávající struktury ověřování pro aplikaci. Neposkytuje žádné funkce pro ověřování uživatelů. Místo toho uživatele ověřujete obvyklým způsobem ve své aplikaci a pak pracujete s výsledky ověřování v kódu SignalR. Můžete například ověřit uživatele pomocí ověřování pomocí ASP.NET formulářů a pak v centru vynutit, kteří uživatelé nebo role mají oprávnění volat metodu. V centru můžete klientovi předat také ověřovací informace, jako je uživatelské jméno nebo to, jestli uživatel patří do role.

SignalR poskytuje atribut Authorize ( Autorizovat ), který určuje, kteří uživatelé mají přístup k centru nebo metodě. Atribut Authorize použijete buď na centrum, nebo na konkrétní metody v centru. Bez atributu Authorize jsou všechny veřejné metody v centru k dispozici klientovi, který je připojený k centru. Další informace o centrech najdete v tématu Ověřování a autorizace pro centra SignalR.

Atribut se Authorize používá pouze u center. Pokud chcete vynutit autorizační pravidla při použití , PersistentConnection musíte přepsat metodu AuthorizeRequest . Další informace o trvalých připojeních najdete v tématu Ověřování a autorizace pro trvalá připojení SignalR.

Token připojení

SignalR snižuje riziko spuštění škodlivých příkazů tím, že ověřuje identitu odesílatele. Pro každý požadavek se mezi klientem a serverem předává token připojení obsahující ID připojení a uživatelské jméno ověřených uživatelů. ID připojení je jedinečný identifikátor, který je náhodně generován serverem při vytvoření nového připojení a je trvalé po dobu trvání připojení. Uživatelské jméno je poskytováno ověřovacím mechanismem webové aplikace. Token připojení je chráněný šifrováním a digitálním podpisem.

Diagram systému tokenů připojení znázorňující vztah mezi klientem, serverem, systémem ověřování a tokenem připojení

U každého požadavku server ověří obsah tokenu, aby se zajistilo, že požadavek pochází od zadaného uživatele. Uživatelské jméno musí odpovídat ID připojení. Tím, že signalR ověřuje ID připojení i uživatelské jméno, zabrání uživateli se zlými úmysly ve snadném zosobnění jiného uživatele. Pokud server nemůže ověřit token připojení, požadavek selže.

Diagram systému tokenů připojení znázorňující vztah mezi klientem, serverem a uloženým tokenem

Vzhledem k tomu, že ID připojení je součástí procesu ověřování, neměli byste id připojení jednoho uživatele prozrazovat jiným uživatelům ani hodnotu ukládat v klientovi, například v souboru cookie.

Opětovné připojení ke skupinám při opětovném připojování

Ve výchozím nastavení aplikace SignalR automaticky znovu přiřadí uživatele k příslušným skupinám při opětovném připojení z dočasného přerušení, například když dojde k ukončení a opětovnému navázání připojení před vypršením časového limitu připojení. Při opětovném připojení klient předá token skupiny, který obsahuje ID připojení a přiřazené skupiny. Token skupiny je digitálně podepsaný a zašifrovaný. Klient si po opětovném připojení zachová stejné ID připojení. PROTO MUSÍ ID připojení předané z znovupřipojeného klienta odpovídat předchozímu ID připojení použitému klientem. Toto ověření zabrání uživateli se zlými úmysly v předávání žádostí o připojení k neoprávněným skupinám při opětovném připojení.

Je však důležité si uvědomit, že platnost tokenu skupiny nevyprší. Pokud uživatel v minulosti patřil do skupiny, ale byl z této skupiny zakázán, může být tento uživatel schopen napodobit token skupiny, který obsahuje zakázanou skupinu. Pokud potřebujete bezpečně spravovat, kteří uživatelé patří do kterých skupin, musíte tato data uložit na serveru, například do databáze. Pak do aplikace přidejte logiku, která na serveru ověří, jestli uživatel patří do skupiny. Příklad ověření členství ve skupinách najdete v tématu Práce se skupinami.

Automatické opětovné připojení ke skupinám se použije jenom v případě, že se připojení po dočasném přerušení znovu připojí. Pokud se uživatel odpojí přechodem mimo aplikaci nebo se aplikace restartuje, musí aplikace zpracovat způsob přidání uživatele do správných skupin. Další informace najdete v tématu Práce se skupinami.

Jak SignalR zabraňuje padělání požadavků napříč weby

Útok CSRF (Cross-Site Request Forgery) je útok, kdy škodlivý web odešle požadavek na ohrožený web, na kterém je uživatel aktuálně přihlášený. SignalR brání CSRF tím, že je velmi nepravděpodobné, aby škodlivý web vytvořil platný požadavek pro vaši aplikaci SignalR.

Popis útoku CSRF

Tady je příklad útoku CSRF:

  1. Uživatel se přihlásí k www.example.comověřování pomocí formulářů.

  2. Server ověří uživatele. Odpověď ze serveru obsahuje ověřovací soubor cookie.

  3. Bez odhlášení uživatel navštíví škodlivý web. Tento škodlivý web obsahuje následující formulář HTML:

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

    Všimněte si, že akce formuláře odešle příspěvek na ohrožený web, ne na škodlivý web. Toto je část CSRF "mezi weby".

  4. Uživatel klikne na tlačítko Odeslat. Prohlížeč do požadavku zahrne ověřovací soubor cookie.

  5. Požadavek se spouští na example.com serveru s kontextem ověřování uživatele a může provádět cokoliv, co má ověřený uživatel povoleno.

I když tento příklad vyžaduje, aby uživatel klikl na tlačítko formuláře, škodlivá stránka by mohla stejně snadno spustit skript, který odešle požadavek AJAX do aplikace SignalR. Navíc použití PROTOKOLU SSL nezabrání útoku CSRF, protože škodlivý web může odeslat požadavek na "https://".

Útoky CSRF jsou obvykle možné na weby, které k ověřování používají soubory cookie, protože prohlížeče odesílají všechny relevantní soubory cookie na cílový web. Útoky CSRF se však neomezují pouze na zneužití souborů cookie. Například základní ověřování a ověřování hodnotou hash jsou také ohroženy. Jakmile se uživatel přihlásí pomocí základního ověřování nebo ověřování hash, prohlížeč automaticky odešle přihlašovací údaje až do ukončení relace.

Zmírnění rizik CSRF, která provádí SignalR

Služba SignalR provede následující kroky, aby zabránila škodlivému webu ve vytváření platných požadavků na vaši aplikaci SignalR. Tyto kroky se provádí ve výchozím nastavení a nevyžadují v kódu žádnou akci.

  • Zákaz mezidoménových požadavků
    Ve výchozím nastavení jsou mezidoménové požadavky v aplikaci SignalR zakázané, aby uživatelé nemohli volat koncový bod SignalR z externí domény. Každý požadavek, který pochází z externí domény, se automaticky považuje za neplatný a zablokuje se. Doporučuje se zachovat toto výchozí chování; Jinak by škodlivý web mohl oklamat uživatele, aby na váš web odesílali příkazy. Pokud potřebujete použít žádosti mezi doménou, přečtěte si téma Jak navázat připojení mezi doménou .
  • Předání tokenu připojení v řetězci dotazu, ne v souboru cookie
    SignalR předá token připojení jako hodnotu řetězce dotazu místo jako soubor cookie. Když se token připojení neuloží jako soubor cookie, prohlížeč ho nechtěně nepředá, když se narazí na škodlivý kód. Token připojení se také neuchovává mimo aktuální připojení. Uživatel se zlými úmysly proto nemůže vytvořit žádost pod přihlašovacími údaji jiného uživatele.
  • Ověření tokenu připojení
    Jak je popsáno v části Token připojení , server ví, které ID připojení je přidružené ke každému ověřenému uživateli. Server nezpracuje žádné požadavky z ID připojení, které neodpovídá uživatelskému jménu. Je nepravděpodobné, že by uživatel se zlými úmysly mohl uhodnout platný požadavek, protože by uživatel se zlými úmysly musel znát uživatelské jméno a aktuální náhodně generované ID připojení. Toto ID připojení se stane neplatným, jakmile se připojení ukončí. Anonymní uživatelé by neměli mít přístup k žádným citlivým informacím.

Doporučení zabezpečení služby SignalR

Protokol SSL (Secure Socket Layer)

Protokol SSL používá šifrování k zabezpečení přenosu dat mezi klientem a serverem. Pokud aplikace SignalR přenáší citlivé informace mezi klientem a serverem, použijte k přenosu protokol SSL. Další informace o nastavení PROTOKOLU SSL najdete v tématu Nastavení SSL ve službě IIS 7.

Nepoužívejte skupiny jako mechanismus zabezpečení.

Skupiny představují pohodlný způsob shromažďování souvisejících uživatelů, ale nejsou bezpečným mechanismem pro omezení přístupu k citlivým informacím. To platí zejména v případě, že se uživatelé můžou automaticky znovu připojit ke skupinám během opětovného připojení. Místo toho zvažte přidání privilegovaných uživatelů do role a omezení přístupu k metodě centra pouze na členy této role. Příklad omezení přístupu na základě role najdete v tématu Ověřování a autorizace pro SignalR Hubs. Příklad kontroly přístupu uživatelů ke skupinám při opětovném připojení najdete v tématu Práce se skupinami.

Bezpečné zpracování vstupu od klientů

Všechny vstupy z klientů, které jsou určeny pro vysílání do jiných klientů, musí být zakódovány, aby se zajistilo, že uživatel se zlými úmysly neodesílá skript ostatním uživatelům. Nejlepší je zakódovat zprávy na přijímajících klientech místo na serveru, protože vaše aplikace SignalR může mít mnoho různých typů klientů. Kódování HTML proto funguje pro webového klienta, ale ne pro jiné typy klientů. Například metoda webového klienta pro zobrazení zprávy chatu by bezpečně zpracovávala uživatelské jméno a zprávu voláním html() funkce.

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>');
};

Odsouhlasení změny stavu uživatele s aktivním připojením

Pokud se stav ověřování uživatele změní, když existuje aktivní připojení, zobrazí se uživateli chyba s informací, že během aktivního připojení SignalR se identita uživatele nemůže změnit. V takovém případě by se vaše aplikace měla znovu připojit k serveru, aby se zajistilo koordinaci ID připojení a uživatelského jména. Pokud například vaše aplikace umožňuje uživateli odhlásit se, když existuje aktivní připojení, uživatelské jméno pro připojení se už nebude shodovat s názvem předaným pro další požadavek. Před odhlášením uživatele budete chtít připojení zastavit a pak ho restartovat.

Je však důležité si uvědomit, že většina aplikací nebude muset připojení ručně zastavit a spustit. Pokud vaše aplikace po odhlášení přesměruje uživatele na samostatnou stránku, například výchozí chování v aplikaci Web Forms nebo aplikaci MVC, nebo aktualizuje aktuální stránku po odhlášení, aktivní připojení se automaticky odpojí a nevyžaduje žádnou další akci.

Následující příklad ukazuje, jak zastavit a spustit připojení při změně stavu uživatele.

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

Nebo se stav ověřování uživatele může změnit, pokud váš web používá posuvné vypršení platnosti s ověřováním pomocí formulářů a neexistuje žádná aktivita, která by zachovala platnost ověřovacího souboru cookie. V takovém případě bude uživatel odhlášený a uživatelské jméno se už nebude shodovat s uživatelským jménem v tokenu připojení. Tento problém můžete vyřešit přidáním skriptu, který pravidelně vyžaduje prostředek na webovém serveru, aby byl ověřovací soubor cookie platný. Následující příklad ukazuje, jak každých 30 minut požádat o prostředek.

$(function () {
    setInterval(function() {
        $.ajax({
            url: "Ping.aspx",
            cache: false
        });
    }, 1800000);
});

Automaticky generované soubory proxy javascriptu

Pokud nechcete zahrnout všechna centra a metody do souboru proxy JavaScriptu pro každého uživatele, můžete zakázat automatické generování souboru. Tuto možnost můžete zvolit, pokud máte více center a metod, ale nechcete, aby všichni uživatelé věděli o všech metodách. Automatické generování zakážete nastavením EnableJavaScriptProxies na false.

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableJavaScriptProxies = false;
RouteTable.Routes.MapHubs("/signalr", hubConfiguration);

Další informace o souborech proxy javascriptu najdete v tématu vygenerovaný proxy server a co pro vás dělá.

Výjimky

Měli byste se vyhnout předávání objektů výjimek klientům, protože objekty můžou klientům vystavit citlivé informace. Místo toho v klientovi zavolejte metodu, která zobrazí příslušnou chybovou zprávu.

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