Leitfaden zur Bedrohungsabwehr für [Blazor Server in ASP.NET CoreThreat mitigation guidance for ASP.NET Core [Blazor Server

Von Javier Calvarro NelsonBy Javier Calvarro Nelson

[Blazor Server-Server-Apps basieren auf einem zustandsbehafteten Datenverarbeitungsmodell, in dem die Beziehung zwischen Server und Client sehr langlebig ist.[Blazor Server apps adopt a stateful data processing model, where the server and client maintain a long-lived relationship. Der persistente Zustand wird durch einen Circuit aufrechterhalten, der mehrere potenziell langlebige Verbindungen umfassen kann.The persistent state is maintained by a circuit, which can span connections that are also potentially long-lived.

Wenn ein Benutzer eine [Blazor Server-Website besucht, erstellt der Server einen Circuit im Arbeitsspeicher des Servers.When a user visits a [Blazor Server site, the server creates a circuit in the server's memory. Der Circuit meldet dem Browser, welche Inhalte dieser rendern und wie dieser auf Ereignisse antworten soll, z. B. wenn der Benutzer in der Benutzeroberfläche auf eine Schaltfläche klickt.The circuit indicates to the browser what content to render and responds to events, such as when the user selects a button in the UI. Für die Ausführung dieser Aktionen ruft ein Circuit JavaScript-Funktionen in den Browser- und .NET-Methoden des Benutzers auf dem Server auf.To perform these actions, a circuit invokes JavaScript functions in the user's browser and .NET methods on the server. Diese bidirektionale JavaScript-basierte Interaktion wird als JavaScript-Interop (JS-Interop) bezeichnet.This two-way JavaScript-based interaction is referred to as JavaScript interop (JS interop).

Da JS-Interop eine Internetverbindung erfordert und der Client einen Remotebrowser verwendet, betreffen die meisten Web-App-Sicherheitsprobleme alle [Blazor Server-Apps.Because JS interop occurs over the Internet and the client uses a remote browser, [Blazor Server apps share most web app security concerns. In diesem Artikel werden häufige Bedrohungen für [Blazor Server-Apps beschrieben. Außerdem enthält er Anleitungen zur Bedrohungsminderung, die auf internetseitige Apps ausgerichtet sind.This topic describes common threats to [Blazor Server apps and provides threat mitigation guidance focused on Internet-facing apps.

In eingeschränkten Umgebungen wie Unternehmensnetzwerken oder Intranets:In constrained environments, such as inside corporate networks or intranets, some of the mitigation guidance either:

  • treffen einige der Hinweise aus diesem Artikel nicht zuDoesn't apply in the constrained environment.
  • rechnen sich die Implementierungskosten für einige der Hinweise aus diesem Artikel nicht, da das Sicherheitsrisiko in eingeschränkten Umgebungen gering ist.Isn't worth the cost to implement because the security risk is low in a constrained environment.

[Blazor und freigegebener Zustand[Blazor and shared state

Blazor-Server-Apps befinden sich im Arbeitsspeicher des Servers.Blazor server apps live in server memory. Das bedeutet, dass innerhalb desselben Prozesses mehrere Apps gehostet werden.That means that there are multiple apps hosted within the same process. Für jede App-Sitzung richtet Blazor eine Verbindung mit seinem eigenen Containerbereich für Abhängigkeitsinjektionen ein.For each app session, Blazor starts a circuit with its own DI container scope. Dies bedeutet, dass bereichsbezogene Dienste pro Blazor-Sitzung eindeutig sind.That means that scoped services are unique per Blazor session.

Warnung

Es wird nicht empfohlen, dass Apps auf demselben Server sich einen Zustand mithilfe von Singletondiensten teilen, es sei denn, es wird mit äußerster Vorsicht vorgegangen, da dies zu Sicherheitsrisiken führen kann, wie z. B. verbindungsübergreifende Preisgabe des Benutzerzustands.We don't recommend apps on the same server share state using singleton services unless extreme care is taken, as this can introduce security vulnerabilities, such as leaking user state across circuits.

Sie können zustandsbehaftete Singletondienste in Blazor-Apps verwenden, sofern sie speziell dafür konzipiert sind.You can use stateful singleton services in Blazor apps if they are specifically designed for it. Beispielsweise ist es in Ordnung, einen Arbeitsspeichercache als Singleton zu verwenden, da ein Schlüssel für den Zugriff auf einen bestimmten Eintrag erforderlich ist, vorausgesetzt, Benutzer haben keine Kontrolle darüber, welche Cacheschlüssel verwendet werden.For example, it's ok to use a memory cache as a singleton because it requires a key to access a given entry, assuming users don't have control of what cache keys are used.

Außerdem dürfen Sie wiederum aus Sicherheitsgründen IHttpContextAccessor nicht in Blazor-Apps verwenden.Additionally, again for security reasons, you must not use IHttpContextAccessor within Blazor apps. Blazor-Apps werden außerhalb des Kontexts der ASP.NET Core-Pipeline ausgeführt.Blazor apps run outside of the context of the ASP.NET Core pipeline. Die Verfügbarkeit von HttpContext in IHttpContextAccessor ist nicht sichergestellt, und es ist auch nicht gewährleistet, dass die Klasse den Kontext zum Starten der Blazor-App enthält.The HttpContext isn't guaranteed to be available within the IHttpContextAccessor, nor is it guaranteed to be holding the context that started the Blazor app.

Der empfohlene Weg der Übergabe des Anforderungszustands an die Blazor-Anwendung ist über Parameter an die Stammkomponente beim ersten Rendern der Anwendung:The recommended way to pass request state to the Blazor app is through parameters to the root component in the initial rendering of the app:

  • Definieren Sie eine Klasse mit allen Daten, die Sie an die Blazor-App übergeben möchten.Define a class with all the data you want to pass to the Blazor app.
  • Füllen Sie diese Daten auf der Razor-Seite mit den zu diesem Zeitpunkt verfügbaren HttpContext.Populate that data from the Razor page using the HttpContext available at that time.
  • Übergeben Sie die Daten an die Blazor-App als Parameter an die Stammkomponente (App).Pass the data to the Blazor app as a parameter to the root component (App).
  • Definieren Sie einen Parameter in der Stammkomponente, der die an die Anwendung zu übergebenden Daten enthält.Define a parameter in the root component to hold the data being passed to the app.
  • Verwenden Sie die benutzerspezifischen Daten innerhalb der App. Alternativ dazu können Sie diese Daten in einen bereichsbezogenen Dienst innerhalb von OnInitializedAsync kopieren, damit sie in der gesamten App verwendet werden können.Use the user-specific data within the app; or alternatively, copy that data into a scoped service within OnInitializedAsync so that it can be used across the app.

Weitere Informationen und Beispielcode finden Sie unter Zusätzliche Sicherheitsszenarios für ASP.NET Core Blazor Server.For more information and example code, see Zusätzliche Sicherheitsszenarios für ASP.NET Core Blazor Server.

RessourcenerschöpfungResource exhaustion

Ressourcenerschöpfung kann auftreten, wenn ein Client mit dem Server interagiert und eine exzessive Ressourcenverbrauch auf dem Server verursacht.Resource exhaustion can occur when a client interacts with the server and causes the server to consume excessive resources. Übermäßiger Ressourcenverbrauch beeinträchtigt maßgeblich die folgenden Komponenten:Excessive resource consumption primarily affects:

Das Ziel von Denial-of-Service-Angriffen (DoS) ist üblicherweise, die Ressourcen einer App oder eines Servers zu erschöpfen.Denial of service (DoS) attacks usually seek to exhaust an app or server's resources. Ressourcenerschöpfung ist jedoch nicht notwendigerweise das Ergebnis eines Angriffs auf das System.However, resource exhaustion isn't necessarily the result of an attack on the system. Endliche Ressourcen können z. B. aufgrund einer hohen Benutzernachfrage aufgebraucht werden.For example, finite resources can be exhausted due to high user demand. Auf DoS-Angriffe wird weiter unten im Abschnitt Denial-of-Service-Angriffe (DoS) eingegangen.DoS is covered further in the Denial of service (DoS) attacks section.

[Blazor-externe Ressourcen wie Datenbanken und Dateihandles (für den Lese- und Schreibvorgänge in Dateien) können ebenso erschöpft werden.Resources external to the [Blazor framework, such as databases and file handles (used to read and write files), may also experience resource exhaustion. Weitere Informationen finden Sie unter Bewährte Methoden für die ASP.net Core Leistung.For more information, see Bewährte Methoden für die ASP.net Core Leistung.

CPUCPU

CPU-Erschöpfung kann auftreten, wenn mindestens ein Client den Server zu CPU-intensiven Prozessen zwingt.CPU exhaustion can occur when one or more clients force the server to perform intensive CPU work.

Ein Beispiel wäre eine [Blazor Server-App, die eine Fibonacci-Zahl berechnet.For example, consider a [Blazor Server app that calculates a Fibonnacci number. Fibonacci-Zahlen sind die Bestandteile einer Fibonnacci-Reihe, in der jede Zahl die Summe der beiden vorherigen Zahlen darstellt.A Fibonnacci number is produced from a Fibonnacci sequence, where each number in the sequence is the sum of the two preceding numbers. Der für die Lösung erforderliche Arbeitsaufwand hängt von der Länge der Reihe und der Größe des ersten Wertes ab.The amount of work required to reach the answer depends on the length of the sequence and the size of the initial value. Wenn die App die Clientanforderung nicht einschränkt, dominieren die CPU-intensiven Berechnungen unter Umständen die CPU-Zeit und schmälern die Leistung von anderen Tasks.If the app doesn't place limits on a client's request, the CPU-intensive calculations may dominate the CPU's time and diminish the performance of other tasks. Exzessiver Ressourcenverbrauch ist ein Sicherheitsproblem, das sich auf die Verfügbarkeit auswirkt.Excessive resource consumption is a security concern impacting availability.

CPU-Erschöpfung ist ein Problem, das alle öffentlich zugänglichen Apps betrifft.CPU exhaustion is a concern for all public-facing apps. In regulären Web-Apps wird für Anforderungen und Verbindungen als Schutzvorkehrung ein Timeoutzeitraum festgelegt. In [Blazor Server-Apps sind diese Schutzmaßnahmen jedoch nicht vorgesehen.In regular web apps, requests and connections time out as a safeguard, but [Blazor Server apps don't provide the same safeguards. [Blazor Server-Apps müssen die richtigen Überprüfungen und Grenzwerte enthalten, bevor potenziell CPU-intensive Prozesse ausgeführt werden.[Blazor Server apps must include appropriate checks and limits before performing potentially CPU-intensive work.

ArbeitsspeicherMemory

Arbeitsspeichererschöpfung kann auftreten, wenn mindestens ein Client den Server zwingt, große Teile des Arbeitsspeichers zu belegen.Memory exhaustion can occur when one or more clients force the server to consume a large amount of memory.

Ein Beispiel wäre eine serverseitige [Blazor-App mit einer Komponente, die eine Elementliste akzeptiert und anzeigt.For example, consider a [Blazor-server side app with a component that accepts and displays a list of items. Wenn die Anzahl der zulässigen Elemente oder die Anzahl der an den Client gerenderten Elemente nicht durch die [Blazor-App eingeschränkt wird, dominieren die arbeitsspeicherintensiven Verarbeitungs- und Renderingprozesse unter Umständen den Arbeitsspeicher des Servers und ziehen die Serverleistung in Mitleidenschaft.If the [Blazor app doesn't place limits on the number of items allowed or the number of items rendered back to the client, the memory-intensive processing and rendering may dominate the server's memory to the point where performance of the server suffers. Der Server kann infolge abstürzen oder so langsam werden, dass es scheint, als sei er abgestürzt.The server may crash or slow to the point that it appears to have crashed.

Stellen Sie sich das folgende Szenario vor, in dem eine Elementliste gewartet und angezeigt wird, die mit einer potenziellen Arbeitsspeichererschöpfung auf dem Server zusammenhängt:Consider the following scenario for maintaining and displaying a list of items that pertain to a potential memory exhaustion scenario on the server:

  • Die Elemente in einer List<MyItem>-Eigenschaft oder einem solchen Feld nutzen den Arbeitsspeicher des Servers.The items in a List<MyItem> property or field use the server's memory. Wenn die App zulässt, dass die Elementliste uneingeschränkt wächst, besteht die Gefahr, dass der Arbeitsspeicher des Servers irgendwann vollständig belegt ist.If the app allows the list of items to grow unbounded, there's a risk of the server running out of memory. Wenn der Arbeitsspeicher erschöpft ist, wird die aktuelle Sitzung beendet (stürzt ab), und alle gleichzeitigen Sitzungen in dieser Serverinstanz empfangen eine Ausnahme mit einem Hinweis auf unzureichenden Arbeitsspeicher.Running out of memory causes the current session to end (crash) and all of the concurrent sessions in that server instance receive an out-of-memory exception. Damit dieses Szenario nicht auftritt, muss die App eine Datenstruktur verwenden, die eine Elementobergrenze für gleichzeitige Benutzer durchsetzt.To prevent this scenario from occurring, the app must use a data structure that imposes an item limit on concurrent users.
  • Wenn beim Rendering kein Paginierungsschema verwendet wird, belegt der Server zusätzlichen Arbeitsspeicher für Objekte, die nicht in der Benutzeroberfläche angezeigt werden.If a paging scheme isn't used for rendering, the server uses additional memory for objects that aren't visible in the UI. Ohne eine Obergrenze für die Anzahl der Elemente kann der verfügbare Arbeitsspeicher durch die Nachfrage erschöpft werden.Without a limit on the number of items, memory demands may exhaust the available server memory. Dieses Szenario lässt sich mit einem der folgenden Ansätze verhindern:To prevent this scenario, use one of the following approaches:
    • Verwenden von paginierten Listen beim RenderingUse paginated lists when rendering.
    • Anzeigen der ersten 100 bis 1.000 Elemente und Durchsetzen, dass Benutzer Suchkriterien eingeben, um andere Elemente als die angezeigten zu findenOnly display the first 100 to 1,000 items and require the user to enter search criteria to find items beyond the items displayed.
    • In einem fortgeschrittenen Renderingszenario können Sie Listen oder Raster implementieren, die Virtualisierung unterstützen.For a more advanced rendering scenario, implement lists or grids that support virtualization. Wenn Virtualisierung eingesetzt wird, rendern Listen nur eine Teilmenge der Elemente, die für den Benutzer aktuell sichtbar sind.Using virtualization, lists only render a subset of items currently visible to the user. Interagiert der Benutzer in der Benutzeroberfläche mit der Scrollleiste, rendert die Komponente nur diejenigen Elemente, die angezeigt werden sollen.When the user interacts with the scrollbar in the UI, the component renders only those items required for display. Aktuell nicht angezeigte Elemente werden idealerweise im sekundären Speicher aufbewahrt.The items that aren't currently required for display can be held in secondary storage, which is the ideal approach. Sie können auch im Speicher abgelegt werden, was jedoch weniger empfehlenswert ist.Undisplayed items can also be held in memory, which is less ideal.

[Blazor Server-Apps bieten ein ähnliches Programmiermodell wie andere Benutzeroberflächenframeworks für zustandsbehaftete Apps wie WPF, Windows Forms oder [Blazor WebAssembly.[Blazor Server apps offer a similar programming model to other UI frameworks for stateful apps, such as WPF, Windows Forms, or [Blazor WebAssembly. Der Hauptunterschied besteht darin, dass der von der App benutzte Arbeitsspeicher in vielen Benutzeroberflächenframeworks dem Client gehört und sich die Auswirkungen daher auf den einzelnen Client beschränken.The main difference is that in several of the UI frameworks the memory consumed by the app belongs to the client and only affects that individual client. Eine [Blazor WebAssembly-App wird z. B. vollständig auf dem Client ausgeführt und verwendet ausschließlich die Arbeitsspeicherressourcen des Clients.For example, a [Blazor WebAssembly app runs entirely on the client and only uses client memory resources. Im [Blazor Server-Szenario gehört der von der App verbrauchte Arbeitsspeicher dem Server und wird von den Clients auf der Serverinstanz gemeinsam genutzt.In the [Blazor Server scenario, the memory consumed by the app belongs to the server and is shared among clients on the server instance.

Der serverseitige Arbeitsspeicherbedarf muss bei allen [Blazor Server-Apps bedacht werden.Server-side memory demands are a consideration for all [Blazor Server apps. Die meisten Web-Apps sind jedoch zustandslos, und der für die Verarbeitung einer Anforderung belegte Arbeitsspeicher wird wieder freigegeben, nachdem die Antwort zurückgegeben wurde.However, most web apps are stateless, and the memory used while processing a request is released when the response is returned. Es ist allgemein empfehlenswert, es Clients nicht zu erlauben, den Arbeitsspeicher uneingeschränkt zu belegen, so wie bei anderen serverseitigen Apps mit dauerhaften Clientverbindungen auch.As a general recommendation, don't permit clients to allocate an unbound amount of memory as in any other server-side app that persists client connections. Der von einer [Blazor Server-App verbrauchte Arbeitsspeicher bleibt auch nach der Verarbeitung einer einzelnen Anforderung belegt.The memory consumed by a [Blazor Server app persists for a longer time than a single request.

Hinweis

Während der Entwicklung kann mithilfe eines Profilers oder einer Überwachung der Arbeitsspeicherbedarf von Clients bewertet werden.During development, a profiler can be used or a trace captured to assess memory demands of clients. Ein Profiler oder eine Überwachung erfassen jedoch nicht den von einem bestimmten Client belegten Arbeitsspeicher.A profiler or trace won't capture the memory allocated to a specific client. Wenn Sie den Arbeitsspeicherverbrauch eines bestimmten Clients während der Entwicklung bestimmen möchten, müssen Sie eine Sicherungskopie erfassen und den Arbeitsspeicherbedarf aller Objekte untersuchen, die sich im Circuit eines Benutzers befinden.To capture the memory use of a specific client during development, capture a dump and examine the memory demand of all the objects rooted at a user's circuit.

ClientverbindungenClient connections

Verbindungserschöpfung kann auftreten, wenn mindestens ein Client zu viele gleichzeitige Verbindungen zum Server geöffnet hat und so andere Clients daran hindert, neue Verbindungen herzustellen.Connection exhaustion can occur when one or more clients open too many concurrent connections to the server, preventing other clients from establishing new connections.

[Blazor-Clients stellen eine Verbindung pro Sitzung her und halten diese so lange offen, wie auch das Browserfenster geöffnet ist.[Blazor clients establish a single connection per session and keep the connection open for as long as the browser window is open. Die Anforderung an den Server, alle Verbindungen aufrechtzuerhalten, ist nicht charakteristisch für [Blazor-Apps.The demands on the server of maintaining all of the connections isn't specific to [Blazor apps. Da die Verbindungen dauerhaft und [Blazor Server-Apps zustandsbehaftet sind, stellt Verbindungserschöpfung ein größeres Risiko für die Verfügbarkeit der App dar.Given the persistent nature of the connections and the stateful nature of [Blazor Server apps, connection exhaustion is a greater risk to availability of the app.

In [Blazor Server-Apps wird die Anzahl der Verbindungen pro Benutzer nicht automatisch beschränkt.By default, there's no limit on the number of connections per user for a [Blazor Server app. Wenn die App eine Verbindungsobergrenze erfordert, sollten Sie mindestens eine der folgenden Maßnahmen ergreifen:If the app requires a connection limit, take one or more of the following approaches:

  • Erzwingen der Authentifizierung, wodurch nicht autorisierten Benutzern automatisch die Möglichkeit genommen wird, eine Verbindung zur App herzustellen.Require authentication, which naturally limits the ability of unauthorized users to connect to the app. Damit dieses Szenario eintritt, müssen Sie verhindern, dass Benutzer willkürlich neue Benutzer bereitstellen.For this scenario to be effective, users must be prevented from provisioning new users at will.
  • Beschränken der pro Benutzer zulässigen Anzahl von Verbindungen.Limit the number of connections per user. Verbindungen lassen sich mithilfe der folgenden Maßnahmen beschränken.Limiting connections can be accomplished via the following approaches. Wägen Sie sorgfältig ab, bevor Sie legitimen Benutzern Zugriff auf die App erteilen (z. B., wenn eine Verbindungsobergrenze für die IP-Adresse eines Clients festgelegt wird).Exercise care to allow legitimate users to access the app (for example, when a connection limit is established based on the client's IP address).
    • Auf App-Ebene:At the app level:
      • Erweiterung des EndpunktroutingsEndpoint routing extensibility.
      • Durchsetzen der Authentifizierung bei der Verbindungsherstellung zur App und Nachverfolgen der aktiven Sitzungen pro BenutzerRequire authentication to connect to the app and keep track of the active sessions per user.
      • Ablehnen neuer Sitzungen, wenn die Obergrenze erreicht wirdReject new sessions upon reaching a limit.
      • Proxy-WebSocket-Verbindungen zu einer App mithilfe eines Proxys wie [Azure SignalR Service. Dieser Dienst bündelt Client-zu-App-Verbindungen.Proxy WebSocket connections to an app through the use of a proxy, such as the [Azure SignalR Service that multiplexes connections from clients to an app. Auf diese Weise kann eine App mehr Verbindungen akzeptieren, als ein einzelner Client herstellen kann. Dies verhindert, dass ein Client alle Verbindungen zum Server belegt.This provides an app with greater connection capacity than a single client can establish, preventing a client from exhausting the connections to the server.
    • Auf Serverebene: Verwenden eines der App vorgeschalteten Proxys/Gateways.At the server level: Use a proxy/gateway in front of the app. Mit Azure Front Door können Sie beispielsweise das globale Routing des Webdatenverkehrs zur App definieren, verwalten und überwachen.For example, Azure Front Door enables you to define, manage, and monitor the global routing of web traffic to an app.

Denial-of-Service-Angriffe (DoS)Denial of service (DoS) attacks

Bei DoS-Angriffen verursacht ein Client die Erschöpfung von mindestens einer Serverressource, sodass die App nicht mehr verfügbar ist.Denial of service (DoS) attacks involve a client causing the server to exhaust one or more of its resources making the app unavailable. [Blazor Server-Apps enthalten einige Standardgrenzwerte und nutzen andere Grenzwerte aus ASP.NET Core und [SignalR, um sich gegen DoS-Angriffe auf CircuitOptions-Objekte zu schützen.[Blazor Server apps include some default limits and rely on other ASP.NET Core and [SignalR limits to protect against DoS attacks that are set on CircuitOptions.

[Blazor Server-App-Grenze[Blazor Server app limit BeschreibungDescription StandardDefault
DisconnectedCircuitMaxRetained Maximale Anzahl der getrennten Circuits, die sich gleichzeitig im Arbeitsspeicher eines bestimmten Servers befindenMaximum number of disconnected circuits that a given server holds in memory at a time. 100100
DisconnectedCircuitRetentionPeriod Maximale Zeitspanne, die ein getrennter Circuit im Arbeitsspeicher aufbewahrt wird, bevor er entfernt wirdMaximum amount of time a disconnected circuit is held in memory before being torn down. 3 Minuten3 minutes
JSInteropDefaultCallTimeout Maximale Zeitspanne, die der Server wartet, bevor der Aufruf einer asynchronen JavaScript-Funktion durch ein Timeout beendet wirdMaximum amount of time the server waits before timing out an asynchronous JavaScript function invocation. 1 Minute1 minute
MaxBufferedUnacknowledgedRenderBatches Maximale Anzahl nicht unbestätigter Renderbatches, die der Server zu einem bestimmten Zeitpunkt pro Circuit im Arbeitsspeicher aufbewahrt, um eine stabile Neuverbindung zu ermöglichen.Maximum number of unacknowledged render batches the server keeps in memory per circuit at a given time to support robust reconnection. Wenn die Obergrenze erreicht wird, generiert der Server keine neuen Renderbatches mehr, bis mindestens ein Batch vom Client bestätigt wurde.After reaching the limit, the server stops producing new render batches until one or more batches have been acknowledged by the client. 1010

Mit <xref:Microsoft.AspNetCore.[SignalR.HubConnectionContextOptions> können Sie die maximale Größe einer einzelnen eingehenden Hubnachricht festlegen.Set the maximum message size of a single incoming hub message with <xref:Microsoft.AspNetCore.[SignalR.HubConnectionContextOptions>.

Grenzwert für [SignalR und ASP.NET Core[SignalR and ASP.NET Core limit BeschreibungDescription StandardDefault
<xref:Microsoft.AspNetCore.[SignalR.HubConnectionContextOptions.MaximumReceiveMessageSize?displayProperty=nameWithType> Nachrichtengröße für eine einzelne NachrichtMessage size for an individual message. 32 KB32 KB

Interaktionen mit dem Browser (Client)Interactions with the browser (client)

Ein Client interagiert über die von JS-Interop gesendeten Ereignisse und Meldungen zur Renderingfertigstellung mit dem Server.A client interacts with the server through JS interop event dispatching and render completion. Die Kommunikation von JS-Interop verläuft bidirektional zwischen JavaScript und .NET:JS interop communication goes both ways between JavaScript and .NET:

  • Browserereignisse werden asynchron vom Client an den Server gesendet.Browser events are dispatched from the client to the server in an asynchronous fashion.
  • Der Server antwortet asynchron und rendert die Benutzeroberfläche nach Bedarf neu.The server responds asynchronously rerendering the UI as necessary.

Über .NET aufgerufene JavaScript-FunktionenJavaScript functions invoked from .NET

Für .NET-Methoden, die JavaScript aufrufen:For calls from .NET methods to JavaScript:

  • Für alle Aufrufe ist ein Timeout festgelegt. Dies bedeutet, dass Aufrufe fehlschlagen, sobald der Wert überschritten wird, und OperationCanceledException an den Aufrufer zurückgegeben wird.All invocations have a configurable timeout after which they fail, returning a OperationCanceledException to the caller.
  • Das Ergebnis eines JavaScript-Aufrufs ist nicht vertrauenswürdig.The result of a JavaScript call can't be trusted. Die [Blazor-App-Client, der im Browser ausgeführt wird, sucht nach der aufzurufenden JavaScript-Funktion.The [Blazor app client running in the browser searches for the JavaScript function to invoke. Die Funktion wird aufgerufen, und es wird entweder das Ergebnis oder ein Fehler zurückgegeben.The function is invoked, and either the result or an error is produced. Ein böswilliger Client kann Folgendes versuchen:A malicious client can attempt to:
    • Verursachen eines Problems in der App, indem von der JavaScript-Funktion ein Fehler zurückgegeben wirdCause an issue in the app by returning an error from the JavaScript function.
    • Einführen eines unbeabsichtigten Verhaltens auf dem Server, indem ein unerwartetes Ergebnis von der JavaScript-Funktion zurückgegeben wirdInduce an unintended behavior on the server by returning an unexpected result from the JavaScript function.

Treffen Sie die folgenden Vorkehrungen, um sich gegen die zuvor genannten Szenarios zu schützen:Take the following precautions to guard against the preceding scenarios:

  • Umschließen Sie Aufrufe von JS-Interop in try-catch-Anweisungen, um während der Aufrufe gegebenenfalls Fehler abzufangen.Wrap JS interop calls within try-catch statements to account for errors that might occur during the invocations. Weitere Informationen finden Sie unter Fehlerbehandlung in ASP.NET Core Blazor-Apps.For more information, see Fehlerbehandlung in ASP.NET Core Blazor-Apps.
  • Überprüfen Sie die Daten, die bei JS-Interop-Aufrufen zurückgegeben werden, einschließlich der Fehlermeldungen, bevor Sie etwas unternehmen.Validate data returned from JS interop invocations, including error messages, before taking any action.

Über den Browser aufgerufene .NET-Methoden.NET methods invoked from the browser

Vertrauen Sie keinen von JavaScript aus aufgerufenen .NET-Methoden.Don't trust calls from JavaScript to .NET methods. Wenn eine .NET-Methode für JavaScript verfügbar gemacht wird, sollten Sie sich ansehen, wie die .NET-Methode aufgerufen wird:When a .NET method is exposed to JavaScript, consider how the .NET method is invoked:

  • Behandeln Sie jede .NET-Methode, die für JavaScript verfügbar gemacht wird, wie einen öffentlichen App-Endpunkt.Treat any .NET method exposed to JavaScript as you would a public endpoint to the app.
    • Überprüfen Sie die Eingabe.Validate input.
      • Stellen Sie sicher, dass die Werte innerhalb der erwarteten Bereiche liegen.Ensure that values are within expected ranges.
      • Stellen Sie sicher, dass der Benutzer dazu berechtigt ist, die angeforderte Aktion auszuführen.Ensure that the user has permission to perform the action requested.
    • Belegen Sie durch den Aufruf der .NET-Methode nicht übermäßig viele Ressourcen.Don't allocate an excessive quantity of resources as part of the .NET method invocation. Führen Sie zum Beispiel Überprüfungen aus, und legen Sie Obergrenzen für die CPU- und Arbeitsspeicherauslastung fest.For example, perform checks and place limits on CPU and memory use.
    • Beachten Sie, dass statische Methoden und Instanzmethoden für JavaScript-Clients verfügbar gemacht werden können.Take into account that static and instance methods can be exposed to JavaScript clients. Zustände sollten nicht sitzungsübergreifend verwendet werden, es sei denn, das Design gibt dies vor, und es sind angemessene Beschränkungen vorgesehen.Avoid sharing state across sessions unless the design calls for sharing state with appropriate constraints.
      • Für Instanzmethoden, die über DotNetReference-Objekte verfügbar gemacht werden, die ursprünglich per Dependency Injection (DI) erstellt wurden, sollten die Objekte als bereichsbezogen registriert werden.For instance methods exposed through DotNetReference objects that are originally created through dependency injection (DI), the objects should be registered as scoped objects. Dies gilt für alle DI-Dienste, die die [Blazor Server-App nutzt.This applies to any DI service that the [Blazor Server app uses.
      • Bei statischen Methoden sollten Sie vermeiden, einen Zustand herzustellen, der sich auf den Client festlegen lässt. Die einzige Ausnahme stellen Apps dar, in denen Zustände absichtlich für alle Benutzer auf einer Serverinstanz verwendet.For static methods, avoid establishing state that can't be scoped to the client unless the app is explicitly sharing state by-design across all users on a server instance.
    • Von Benutzern bereitgestellte Daten sollten nicht als Parameter für JavaScript-Aufrufe genutzt werden.Avoid passing user-supplied data in parameters to JavaScript calls. Wenn das Übergeben von Daten in Parametern absolut notwendig ist, sollten Sie sicherstellen, dass der JavaScript-Code bei der Datenübergabe keine Gelegenheit für Cross-Site-Scripting (XSS) bietet.If passing data in parameters is absolutely required, ensure that the JavaScript code handles passing the data without introducing Cross-site scripting (XSS) vulnerabilities. Schreiben Sie beispielsweise keine von Benutzern bereitgestellten Daten in das Dokumentobjektmodell (DOM), indem Sie die Eigenschaft innerHTML eines Elements festlegen.For example, don't write user-supplied data to the Document Object Model (DOM) by setting the innerHTML property of an element. Außerdem können Sie mit Content Security Policy (zu Deutsch: „Richtlinie für Inhaltssicherheit“) ggf. eval und andere unsichere primitive JavaScript-Datentypen deaktivieren.Consider using Content Security Policy (CSP) to disable eval and other unsafe JavaScript primitives.
  • Implementieren Sie keine benutzerdefinierte Sendung von .NET-Aufrufen zusätzlich zur Sendungsimplementierung des Frameworks.Avoid implementing custom dispatching of .NET invocations on top of the framework's dispatching implementation. Das Verfügbarmachen von .NET-Methoden für den Browser ist ein fortgeschrittenes Szenario, das sich nicht als allgemeine [Blazor-Entwicklungstechnik empfiehlt.Exposing .NET methods to the browser is an advanced scenario, not recommended for general [Blazor development.

EreignisseEvents

Ereignisse stellen einen Einstiegspunkt in eine [Blazor Server-App dar.Events provide an entry point to a [Blazor Server app. Für das Ereignishandling in [Blazor Server-Apps gelten dieselben Regeln wie für das Schützen von Endpunkten in Web-Apps.The same rules for safeguarding endpoints in web apps apply to event handling in [Blazor Server apps. Ein böswilliger Client kann beliebige Daten als Nutzlast für ein Ereignis senden.A malicious client can send any data it wishes to send as the payload for an event.

Zum Beispiel:For example:

  • Ein Änderungsereignis für <select> könnte einen Wert senden, der nicht innerhalb der Optionen liegt, die die App dem Client präsentiert hat.A change event for a <select> could send a value that isn't within the options that the app presented to the client.
  • <input> könnte beliebige Textdaten an den Server senden und dabei die clientseitige Überprüfung umgehen.An <input> could send any text data to the server, bypassing client-side validation.

Die App muss die Daten für alle Ereignisse überprüfen, die die App verarbeitet.The app must validate the data for any event that the app handles. Die Formularkomponenten des [Blazor-Frameworks führen grundlegende Überprüfungen aus.The [Blazor framework forms components perform basic validations. Wenn die App benutzerdefinierte Formularkomponenten verwendet, müssen Benutzer Code schreiben, damit die Ereignisdaten richtig ausgewertet werden.If the app uses custom forms components, custom code must be written to validate event data as appropriate.

[Blazor Server-Ereignisse sind asynchron, sodass mehrere Ereignisse an den Server gesendet werden können, bevor die App darauf reagieren und ein neues Rendering produzieren kann.[Blazor Server events are asynchronous, so multiple events can be dispatched to the server before the app has time to react by producing a new render. Dies birgt einige Sicherheitsrisiken, die bedacht werden sollten.This has some security implications to consider. Clientaktionen in der App müssen innerhalb des Ereignishandlers beschränkt werden und dürfen nicht vom aktuell gerenderten Anzeigezustand abhängen.Limiting client actions in the app must be performed inside event handlers and not depend on the current rendered view state.

Stellen Sie sich eine Zählerkomponente vor, mit der ein Benutzer einen Zähler höchstens dreimal erhöhen können soll.Consider a counter component that should allow a user to increment a counter a maximum of three times. Die Schaltfläche zum Hochsetzen des Zählers basiert bedingungsweise auf dem Wert von count:The button to increment the counter is conditionally based on the value of count:

<p>Count: @count<p>

@if (count < 3)
{
    <button @onclick="IncrementCount" value="Increment count" />
}

@code 
{
    private int count = 0;

    private void IncrementCount()
    {
        count++;
    }
}

Ein Client kann mindestens ein Inkrementierungsereignis senden, bevor das Framework ein neues Rendering dieser Komponente generiert.A client can dispatch one or more increment events before the framework produces a new render of this component. Dies führt dazu, dass count mehr als dreimal vom Benutzer inkrementiert werden kann, weil die Schaltfläche nicht schnell genug aus der Benutzeroberfläche entfernt wird.The result is that the count can be incremented over three times by the user because the button isn't removed by the UI quickly enough. Die richtige Vorgehensweise für das Durchsetzen der Obergrenze von drei count-Inkrementen wird im folgenden Beispiel veranschaulicht:The correct way to achieve the limit of three count increments is shown in the following example:

<p>Count: @count<p>

@if (count < 3)
{
    <button @onclick="IncrementCount" value="Increment count" />
}

@code 
{
    private int count = 0;

    private void IncrementCount()
    {
        if (count < 3)
        {
            count++;
        }
    }
}

Indem die Überprüfung if (count < 3) { ... } innerhalb des Handlers hinzugefügt wird, wird die Entscheidung über das Inkrementieren von count anhand des aktuellen App-Zustands getroffen.By adding the if (count < 3) { ... } check inside the handler, the decision to increment count is based on the current app state. Die Entscheidung basiert nicht wie im vorherigen Beispiel auf dem Zustand der Benutzeroberfläche, der vorübergehen veraltet sein kann.The decision isn't based on the state of the UI as it was in the previous example, which might be temporarily stale.

Wächter gegen mehrere SendungenGuard against multiple dispatches

Wenn ein Ereignisrückruf einen zeitintensiven Vorgang wie das Abrufen von Daten aus einem externen Dienst oder einer Datenbank asynchron aufruft, sollten Sie möglicherweise einen Wächter einsetzen.If an event callback invokes a long running operation asynchronously, such as fetching data from an external service or database, consider using a guard. Der Wächter kann verhindern, dass Benutzer mehrere Vorgänge an die Warteschlange senden, während der Vorgang bearbeitet und visuelles Feedback geliefert wird.The guard can prevent the user from queueing up multiple operations while the operation is in progress with visual feedback. Der folgende Komponentencode legt isLoading auf true fest, während GetForecastAsync Daten vom Server abruft.The following component code sets isLoading to true while GetForecastAsync obtains data from the server. Während isLoading true ist, ist die Schaltfläche in der Benutzeroberfläche deaktiviert:While isLoading is true, the button is disabled in the UI:

@page "/fetchdata"
@using BlazorServerSample.Data
@inject WeatherForecastService ForecastService

<button disabled="@isLoading" @onclick="UpdateForecasts">Update</button>

@code {
    private bool isLoading;
    private WeatherForecast[] forecasts;

    private async Task UpdateForecasts()
    {
        if (!isLoading)
        {
            isLoading = true;
            forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
            isLoading = false;
        }
    }
}

Das im vorherigen Beispiel gezeigte Wächtermuster funktioniert, wenn der Hintergrundvorgang asynchron mit dem async-await-Muster ausgeführt wird.The guard pattern demonstrated in the preceding example works if the background operation is executed asynchronously with the async-await pattern.

Frühes Abbrechen und Vermeiden der Verwendung nach der Entfernung (use-after-dispose)Cancel early and avoid use-after-dispose

Zusätzlich zu einem Wächter (Abschnitt Wächter gegen mehrere Sendungen) sollten Sie auch ein Abbruchtoken (CancellationToken) verwenden, um zeitintensive Vorgänge nach dem Entfernen der Komponente abbrechen zu können.In addition to using a guard as described in the Guard against multiple dispatches section, consider using a CancellationToken to cancel long-running operations when the component is disposed. Dieser Ansatz bietet den zusätzlichen Vorteil, dass eine Verwendung nach der Entfernung (use-after-dispose) in Komponenten vermieden wird:This approach has the added benefit of avoiding use-after-dispose in components:

@implements IDisposable

...

@code {
    private readonly CancellationTokenSource TokenSource = 
        new CancellationTokenSource();

    private async Task UpdateForecasts()
    {
        ...

        forecasts = await ForecastService.GetForecastAsync(DateTime.Now, 
            TokenSource.Token);

        if (TokenSource.Token.IsCancellationRequested)
        {
           return;
        }

        ...
    }

    public void Dispose()
    {
        TokenSource.Cancel();
    }
}

Vermeiden von großen Datenmengen produzierenden EreignissenAvoid events that produce large amounts of data

Einige DOM-Ereignisse wie oninput oder onscroll können eine große Menge von Daten generieren.Some DOM events, such as oninput or onscroll, can produce a large amount of data. Diese Ereignisse sollten nicht in [Blazor-Server-Apps verwendet werden.Avoid using these events in [Blazor server apps.

Zusätzlicher SicherheitsleitfadenAdditional security guidance

Der Leitfaden zur Sicherung von ASP.NET Core-Apps gilt für [Blazor Server-Apps und enthält die folgenden Abschnitte:The guidance for securing ASP.NET Core apps apply to [Blazor Server apps and are covered in the following sections:

Protokollierung und vertrauliche DatenLogging and sensitive data

JS-Interop-Interaktionen zwischen dem Client und dem Server werden in den Serverprotokollen mit ILogger-Instanzen erfasst.JS interop interactions between the client and server are recorded in the server's logs with ILogger instances. In [Blazor werden keine vertraulichen Informationen wie tatsächliche Ereignisse oder JS-Interop-Ein- und -Ausgaben protokolliert.[Blazor avoids logging sensitive information, such as actual events or JS interop inputs and outputs.

Wenn auf dem Server ein Fehler auftritt, benachrichtigt das Framework den Client und beendet die Sitzung.When an error occurs on the server, the framework notifies the client and tears down the session. Der Client empfängt automatisch eine Standardfehlermeldung, die in den Entwicklertools des Browsers aufgerufen werden kann.By default, the client receives a generic error message that can be seen in the browser's developer tools.

Die clientseitige Fehlermeldung enthält weder den Aufrufstapel noch Details zur Fehlerursache, die Serverprotokolle hingegen schon.The client-side error doesn't include the callstack and doesn't provide detail on the cause of the error, but server logs do contain such information. Zu Entwicklungszwecken können vertrauliche Fehlerinformationen für den Client verfügbar gemacht werden, indem Sie detaillierte Fehlermeldungen aktivieren.For development purposes, sensitive error information can be made available to the client by enabling detailed errors.

In JavaScript werden detaillierte Fehlermeldungen wie folgt aktiviert:Enable detailed errors in JavaScript with:

  • CircuitOptions.DetailedErrorsCircuitOptions.DetailedErrors.
  • Der Konfigurationsschlüssel DetailedErrors muss auf true festgelegt werden. Diese Einstellung können Sie in der Einstellungsdatei der App (appsettings.json) vornehmen.The DetailedErrors configuration key set to true, which can be set in the app settings file (appsettings.json). Der Schlüssel lässt sich darüber hinaus mithilfe der Umgebungsvariablen ASPNETCORE_DETAILEDERRORS auf den Wert true festlegen.The key can also be set using the ASPNETCORE_DETAILEDERRORS environment variable with a value of true.

Warnung

Das Verfügbarmachen von Fehlerinformationen für internetseitige Clients ist ein Sicherheitsrisiko, dass immer vermieden werden sollte.Exposing error information to clients on the Internet is a security risk that should always be avoided.

Schützen von Informationen während der Übertragung mit HTTPSProtect information in transit with HTTPS

[Blazor Server stellt die Kommunikation zwischen Client und Server mithilfe von [SignalR bereit.[Blazor Server uses [SignalR for communication between the client and the server. Normalerweise verwendet [Blazor Server den Transport, der von [SignalR ausgehandelt wird. Dabei handelt es sich in der Regel um WebSockets.[Blazor Server normally uses the transport that [SignalR negotiates, which is typically WebSockets.

[Blazor Server bietet keine Garantie für die Integrität und Vertraulichkeit der Daten, die zwischen Server und Client gesendet werden.[Blazor Server doesn't ensure the integrity and confidentiality of the data sent between the server and the client. Verwenden Sie daher immer HTTPS.Always use HTTPS.

Cross-Site-Scripting (XSS)Cross-site scripting (XSS)

XSS ermöglicht es einem nicht autorisierten Benutzer, eine beliebige Logik im Kontext des Browsers auszuführen.Cross-site scripting (XSS) allows an unauthorized party to execute arbitrary logic in the context of the browser. Eine kompromittierte App kann beliebigen Code auf dem Client ausführen.A compromised app could potentially run arbitrary code on the client. Das Sicherheitsrisiko kann ausgenutzt werden, um eine Reihe schädlicher Aktionen für den Server auszuführen:The vulnerability could be used to potentially perform a number of malicious actions against the server:

  • Senden gefälschter/ungültiger Ereignisse an den ServerDispatch fake/invalid events to the server.
  • Senden von fehlgeschlagenen/ungültigen Meldungen zur RenderingfertigstellungDispatch fail/invalid render completions.
  • Vermeiden des Sendens von Meldungen zur RenderingfertigstellungAvoid dispatching render completions.
  • Senden von Interop-Aufrufen aus JavaScript an .NETDispatch interop calls from JavaScript to .NET.
  • Ändern der Antwort von Interop-Aufrufen aus .NET an JavaScriptModify the response of interop calls from .NET to JavaScript.
  • Vermeiden des Sendens von .NET-Ergebnissen an JS-InteropAvoid dispatching .NET to JS interop results.

Das [Blazor Server-Framework bietet die folgenden Maßnahmen zum Schutz vor einigen der zuvor genannten Bedrohungen:The [Blazor Server framework takes steps to protect against some of the preceding threats:

  • Es werden keine neuen Benutzeroberflächenupdates generiert, wenn der Client die Renderbatches nicht bestätigt.Stops producing new UI updates if the client isn't acknowledging render batches. Dies wird mit CircuitOptions.MaxBufferedUnacknowledgedRenderBatches konfiguriert.Configured with CircuitOptions.MaxBufferedUnacknowledgedRenderBatches.
  • Für alle JavaScript-Aufrufe von .NET aus tritt nach einer Minute ein Timeout auf, ohne dass der Client eine Antwort sendet.Times out any .NET to JavaScript call after one minute without receiving a response from the client. Dies wird mit CircuitOptions.JSInteropDefaultCallTimeout konfiguriert.Configured with CircuitOptions.JSInteropDefaultCallTimeout.
  • Während JS-Interop wird eine grundlegende Überprüfung für alle Eingaben ausgeführt, die aus dem Browser stammen:Performs basic validation on all input coming from the browser during JS interop:
    • .NET-Verweise sind gültig und weisen den von der .NET-Methode erwarteten Typ auf..NET references are valid and of the type expected by the .NET method.
    • Die Daten sind nicht falsch formatiert.The data isn't malformed.
    • Die Nutzlast enthält die korrekte Anzahl von Argumenten für die Methode.The correct number of arguments for the method are present in the payload.
    • Die Argumente oder das Ergebnis lässt sich korrekt deserialisieren, bevor die Methode aufgerufen wird.The arguments or result can be deserialized correctly before invoking the method.
  • Eine grundlegende Überprüfung wird für alle Eingaben ausgeführt, die aus dem Browser aus gesendeten Ereignissen stammen:Performs basic validation in all input coming from the browser from dispatched events:
    • Das Ereignis weist einen gültigen Typ auf.The event has a valid type.
    • Die Daten für das Ereignis lassen sich deserialisieren.The data for the event can be deserialized.
    • Es gibt einen Ereignishandler, der dem Ereignis zugeordnet ist.There's an event handler associated with the event.

Zusätzlich zu den vom Framework implementierten Schutzmaßnahmen muss die App vom Entwickler so programmiert werden, dass sie gegen Bedrohungen geschützt ist und die angemessenen Aktionen ausführen kann:In addition to the safeguards that the framework implements, the app must be coded by the developer to safeguard against threats and take appropriate actions:

  • Beim Ereignishandling müssen Daten immer überprüft werden.Always validate data when handling events.
  • Werden ungültige Daten empfangen, müssen die angemessenen Aktionen ausgeführt werden:Take appropriate action upon receiving invalid data:
    • Die Daten und die Rückgabe müssen ignoriert werden.Ignore the data and return. Dies ermöglicht es der App, weiterhin Anforderungen zu verarbeiten.This allows the app to continue processing requests.
    • Wenn die App eine ungültige Eingabe erkennt, die nicht von einem legitimen Client stammen kann, wird eine Ausnahme zurückgegeben.If the app determines that the input is illegitimate and couldn't be produced by legitimate client, throw an exception. Aufgrund der Ausnahme werden sowohl der Circuit als auch die Sitzung beendet.Throwing an exception tears down the circuit and ends the session.
  • Vertrauen Sie nicht der Fehlermeldung, die in den Fertigstellungsmeldungen zum Batchrendering in den Protokollen enthalten ist.Don't trust the error message provided by render batch completions included in the logs. Sie stammt vom Client und ist allgemein nicht vertrauenswürdig, da der Client möglicherweise kompromittiert ist.The error is provided by the client and can't generally be trusted, as the client might be compromised.
  • Vertrauen Sie nicht der Eingabe für JS-Interop-Aufrufe zwischen JavaScript und .NET-Methoden (beide Richtungen).Don't trust the input on JS interop calls in either direction between JavaScript and .NET methods.
  • Die App ist dafür zuständig, dass die Gültigkeit der Argumente und Ergebnisse überprüft wird, selbst wenn die Argumente oder Ergebnisse korrekt deserialisiert wurden.The app is responsible for validating that the content of arguments and results are valid, even if the arguments or results are correctly deserialized.

Das Risiko von XSS besteht nur, wenn die App Benutzereingaben in die gerenderte Seite einbindet.For a XSS vulnerability to exist, the app must incorporate user input in the rendered page. [Blazor Server-Komponenten führen einen Schritt zur Kompilierzeit aus, bei dem Markup in einer .razor-Datei in eine prozedurale C#-Logik transformiert wird.[Blazor Server components execute a compile-time step where the markup in a .razor file is transformed into procedural C# logic. Zur Laufzeit erstellt die C#-Logik eine Renderingstruktur, die die Elemente, den Text und die untergeordneten Komponenten beschreibt.At runtime, the C# logic builds a render tree describing the elements, text, and child components. Diese wird mithilfe mehrerer JavaScript-Anweisungen auf das DOM des Browsers angewendet (oder im Falle von Prerendering in HTML serialisiert):This is applied to the browser's DOM via a sequence of JavaScript instructions (or is serialized to HTML in the case of prerendering):

  • Benutzereingaben, die über eine normale [Razor-Syntax gerendert werden (z. B. @someStringValue) stellen kein XSS-Risiko dar, weil die [Razor-Syntax mithilfe von Befehlen, die nur Text schreiben können, dem DOM hinzugefügt wird.User input rendered via normal [Razor syntax (for example, @someStringValue) doesn't expose a XSS vulnerability because the [Razor syntax is added to the DOM via commands that can only write text. Selbst wenn der Wert HTML-Markup enthält, wird er als statischer Text angezeigt.Even if the value includes HTML markup, the value is displayed as static text. Während des Prerenderings wird die Ausgabe HTML-codiert, wodurch der Inhalt ebenfalls als statischer Text angezeigt wird.When prerendering, the output is HTML-encoded, which also displays the content as static text.
  • Skripttags sind nicht zulässig und sollten in der Komponentenrenderingstruktur der App nicht verwendet werden.Script tags aren't allowed and shouldn't be included in the app's component render tree. Wenn Sie ein Skripttag das Markup einer Komponente aufnehmen, wird ein Kompilierzeitfehler zurückgegeben.If a script tag is included in a component's markup, a compile-time error is generated.
  • Komponentenersteller können auch ohne [Razor Komponenten in C# erstellen.Component authors can author components in C# without using [Razor. Der Komponentenersteller ist dafür verantwortlich, das beim Ausgeben der Ausgabe die richtigen APIs benutzt werden.The component author is responsible for using the correct APIs when emitting output. Es muss beispielsweise builder.AddContent(0, someUserSuppliedString) und nicht builder.AddMarkupContent(0, someUserSuppliedString) verwendet werden, da letztere API das Risiko von XSS birgt.For example, use builder.AddContent(0, someUserSuppliedString) and not builder.AddMarkupContent(0, someUserSuppliedString), as the latter could create a XSS vulnerability.

Zum Schutz vor XSS-Angriffen können Sie auch Maßnahmen zur Risikominderung ergreifen, z. B. Content Security Policy (CSP) konfigurieren.As part of protecting against XSS attacks, consider implementing XSS mitigations, such as Content Security Policy (CSP).

Weitere Informationen finden Sie unter Verhindern von Cross-Site Scripting (XSS) in ASP.net Core.For more information, see Verhindern von Cross-Site Scripting (XSS) in ASP.net Core.

Ursprungsübergreifender SchutzCross-origin protection

Bei ursprungsübergreifenden Angriffen führt ein Client, der einen anderen Ursprung hat, eine Aktion für den Server aus.Cross-origin attacks involve a client from a different origin performing an action against the server. Bei der böswilligen Aktion handelt es sich üblicherweise um eine GET-Anforderung oder eine Art von POST-Methode (Cross-Site Request Forgery, CSRF). Es ist jedoch ebenso möglich, dass eine böswillige WebSocket-Verbindung geöffnet wird.The malicious action is typically a GET request or a form POST (Cross-Site Request Forgery, CSRF), but opening a malicious WebSocket is also possible. [Blazor Server-Apps bieten [dieselben Garantien wie jede andere SignalR-App, die das angebotene Hubprotokoll verwendet:[Blazor Server apps offer [the same guarantees that any other SignalR app using the hub protocol offer:

  • Es besteht ursprungsübergreifender Zugriff auf [Blazor Server-Apps, es sei denn, dies wird durch zusätzliche Schutzmaßnahmen verhindert.[Blazor Server apps can be accessed cross-origin unless additional measures are taken to prevent it. Wenn Sie den ursprungsübergreifenden Zugriff deaktivieren möchten, müssen Sie entweder Cross-Origin Resource Sharing (CORS) im Endpunkt deaktivieren, indem Sie die CORS-Middleware der Pipeline und das DisableCorsAttribute-Objekt den Metadaten des [Blazor-Endpunkts hinzufügen oder die zulässigen Ursprünge eingrenzen, indem Sie [SignalR für Cross-Origin Resource Sharing konfigurieren.To disable cross-origin access, either disable CORS in the endpoint by adding the CORS middleware to the pipeline and adding the DisableCorsAttribute to the [Blazor endpoint metadata or limit the set of allowed origins by [configuring SignalR for cross-origin resource sharing.
  • Wenn CORS aktiviert ist, sind je nach CORS-Konfiguration unter Umständen weitere Schritte erforderlich, um die App zu schützen.If CORS is enabled, extra steps might be required to protect the app depending on the CORS configuration. Ist CORS global aktiviert, lässt sich der Mechanismus für den [Blazor Server-Hub deaktivieren, indem die DisableCorsAttribute-Metadaten den Endpunktmetadaten hinzugefügt werden, nachdem MapBlazorHub im Endpunktroutengenerator aufgerufen wurde.If CORS is globally enabled, CORS can be disabled for the [Blazor Server hub by adding the DisableCorsAttribute metadata to the endpoint metadata after calling MapBlazorHub on the endpoint route builder.

Weitere Informationen finden Sie unter Verhindern von Angriffen für Website übergreifende Anforderungs Fälschung (XSRF/CSRF) in ASP.net Core.For more information, see Verhindern von Angriffen für Website übergreifende Anforderungs Fälschung (XSRF/CSRF) in ASP.net Core.

ClickjackingClick-jacking

Beim Clickjacking wird eine Website als <iframe> innerhalb einer Website gerendert, die einen anderen Ursprung hat. So soll der Benutzer überlistet und dazu gebracht werden, Aktionen auf der angegriffenen Website auszuführen.Click-jacking involves rendering a site as an <iframe> inside a site from a different origin in order to trick the user into performing actions on the site under attack.

Mithilfe von Content Security Policy (CSP) und dem Header X-Frame-Options können Sie eine App davor schützen, innerhalb eines Inlineframes (<iframe>) gerendert zu werden.To protect an app from rendering inside of an <iframe>, use Content Security Policy (CSP) and the X-Frame-Options header. Weitere Informationen finden Sie unter MDN Web Docs: X-Frame-Options.For more information, see MDN web docs: X-Frame-Options.

Open RedirectsOpen redirects

Wenn eine [Blazor Server-App-Sitzung beginnt, überprüft der Server grundlegend die URLs, die beim Sitzungsstart gesendet wurden.When a [Blazor Server app session starts, the server performs basic validation of the URLs sent as part of starting the session. Das Framework überprüft, ob es sich bei der Basis-URL um eine übergeordnete URL der aktuellen handelt, bevor der Circuit hergestellt wird.The framework checks that the base URL is a parent of the current URL before establishing the circuit. Weitere Überprüfungen führt das Framework nicht aus.No additional checks are performed by the framework.

Wenn ein Benutzer auf dem Client auf einen Link klickt, wird die Link-URL an den Server gesendet. Dieser entscheidet wiederum, welche Aktion anschließend ausgeführt wird.When a user selects a link on the client, the URL for the link is sent to the server, which determines what action to take. Die App kann beispielsweise eine clientseitige Navigation ausführen oder den Browser anweisen, einen neuen Inhalt aufzurufen.For example, the app may perform a client-side navigation or indicate to the browser to go to the new location.

Komponenten können außerdem mithilfe von NavigationManager Navigationsanforderungen programmgesteuert auslösen.Components can also trigger navigation requests programatically through the use of NavigationManager. In einem solchen Szenario kann die App eine clientseitige Navigation ausführen oder den Browser anweisen, einen neuen Inhalt aufzurufen.In such scenarios, the app might perform a client-side navigation or indicate to the browser to go to the new location.

Für Komponenten gilt Folgendes:Components must:

  • Benutzereingaben dürfen nicht in Argumenten von Navigationsaufrufen verwendet werden.Avoid using user input as part of the navigation call arguments.
  • Argumente müssen überprüft werden, um sicherzustellen, dass das Ziel von der App erlaubt wird.Validate arguments to ensure that the target is allowed by the app.

Andernfalls kann ein böswilliger Benutzer den Browser zwingen, eine vom Angreifer kontrollierte Website aufzurufen.Otherwise, a malicious user can force the browser to go to an attacker-controlled site. In diesem Szenario überlistet der Angreifer die App, sodass diese eine Benutzereingabe im Rahmen eines Aufrufs der NavigationManager.NavigateTo-Methode verwendet.In this scenario, the attacker tricks the app into using some user input as part of the invocation of the NavigationManager.NavigateTo method.

Diese Empfehlung gilt auch, wenn Links als App-Inhalt gerendert werden:This advice also applies when rendering links as part of the app:

  • Wenn möglich, sollten Sie sich immer für relative Links entscheiden.If possible, use relative links.
  • Überprüfen Sie, ob die Ziele von absoluten Links gültig sind, bevor Sie die Links in eine Seite einbetten.Validate that absolute link destinations are valid before including them in a page.

Weitere Informationen finden Sie unter Verhindern offener Weiterleitungs Angriffe in ASP.net Core.For more information, see Verhindern offener Weiterleitungs Angriffe in ASP.net Core.

Checkliste für die SicherheitSecurity checklist

Die folgende Liste von Sicherheitsmaßnahmen ist nicht abschließend:The following list of security considerations isn't comprehensive:

  • Überprüfen Sie die Argumente von Ereignissen.Validate arguments from events.
  • Überprüfen Sie die Eingaben und Ergebnisse aus JS-Interop-Aufrufen.Validate inputs and results from JS interop calls.
  • Vermeiden Sie Benutzereingaben in JS-Interop-Aufrufen von .NET aus (oder überprüfen Sie diese vorher).Avoid using (or validate beforehand) user input for .NET to JS interop calls.
  • Verhindern Sie, dass der Client unbegrenzt Arbeitsspeicher belegen kann.Prevent the client from allocating an unbound amount of memory.
    • Daten innerhalb der KomponenteData within the component.
    • DotNetObject-Verweise, die an den Client zurückgegeben werdenDotNetObject references returned to the client.
  • Schützen Sie sich vor mehreren Sendungen.Guard against multiple dispatches.
  • Brechen Sie zeitintensive Vorgängen ab, wenn die Komponente entfernt wird.Cancel long-running operations when the component is disposed.
  • Vermeiden Sie Ereignisse, die große Datenmengen produzieren.Avoid events that produce large amounts of data.
  • Benutzereingaben sollten nie für NavigationManager.NavigateTo-Aufrufe verwendet werden, und überprüfen Sie Benutzereingaben für URLs zuerst auf zulässige Ursprünge, wenn dies unvermeidlich ist.Avoid using user input as part of calls to NavigationManager.NavigateTo and validate user input for URLs against a set of allowed origins first if unavoidable.
  • Treffen Sie keine Autorisierungsentscheidungen auf Grundlage des Zustands der Benutzeroberfläche, sondern nur anhand des Komponentenzustands.Don't make authorization decisions based on the state of the UI but only from component state.
  • Verwenden Sie ggf. Content Security Policy (CSP), um Apps vor XSS-Angriffen zu schützen.Consider using Content Security Policy (CSP) to protect against XSS attacks.
  • Verwenden Sie ggf. CSP und X-Frame-Options, um Apps vor Clickjacking zu schützen.Consider using CSP and X-Frame-Options to protect against click-jacking.
  • Stellen Sie sicher, dass die CORS-Einstellungen angemessen sind, wenn Sie CORS aktivieren, oder deaktivieren Sie CORS explizit für [Blazor-Apps.Ensure CORS settings are appropriate when enabling CORS or explicitly disable CORS for [Blazor apps.
  • Führen Sie Tests durch, um sicherzustellen, dass die serverseitigen Grenzwerte für die [Blazor-App eine akzeptable Nutzungsqualität gewährleisten und keine nicht akzeptablen Risiken bergen.Test to ensure that the server-side limits for the [Blazor app provide an acceptable user experience without unacceptable levels of risk.