ASP.NET Core Blazor Server の脅威の緩和のガイダンスThreat mitigation guidance for ASP.NET Core Blazor Server

作成者: Javier Calvarro JeannineBy Javier Calvarro Nelson

Blazor Server アプリでは、サーバーとクライアントが長期間のリレーションシップを維持する、"ステートフル" なデータ処理モデルが採用されています。Blazor Server apps adopt a stateful data processing model, where the server and client maintain a long-lived relationship. 永続的な状態は回線によって維持されます。これは、長期間続く可能性がある接続にまたがることがあります。The persistent state is maintained by a circuit, which can span connections that are also potentially long-lived.

ユーザーが Blazor Server サイトにアクセスすると、サーバーによってサーバーのメモリに回線が作成されます。When a user visits a Blazor Server site, the server creates a circuit in the server's memory. ユーザーが UI のボタンを選択したときなどに、この回線によって、レンダリングするコンテンツがブラウザーに指示されたり、イベントへの応答が行われたりします。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. これらのアクションを実行するために、回線によって、ユーザーのブラウザーで JavaScript 関数が呼び出され、サーバー上で .NET メソッドが呼び出されます。To perform these actions, a circuit invokes JavaScript functions in the user's browser and .NET methods on the server. この JavaScript ベースの双方向の対話は、JavaScript 相互運用 (JS 相互運用) と呼ばれます。This two-way JavaScript-based interaction is referred to as JavaScript interop (JS interop).

JS 相互運用はインターネット経由で行われ、クライアントではリモート ブラウザーが使用されるため、Blazor Server アプリではほとんどの Web アプリのセキュリティの問題が共有されています。Because JS interop occurs over the Internet and the client uses a remote browser, Blazor Server apps share most web app security concerns. このトピックでは、Blazor Server アプリに対する一般的な脅威について説明し、インターネットに接続されたアプリに重点を置いた脅威の緩和のガイダンスを提供します。This topic describes common threats to Blazor Server apps and provides threat mitigation guidance focused on Internet-facing apps.

企業ネットワーク内やイントラネット内などの制約された環境では、緩和ガイダンスの一部は、次のいずれかになります。In constrained environments, such as inside corporate networks or intranets, some of the mitigation guidance either:

  • 制約された環境には適用されません。Doesn't apply in the constrained environment.
  • 制約された環境はセキュリティ リスクが低いため、実装する価値がありません。Isn't worth the cost to implement because the security risk is low in a constrained environment.

Blazor と共有状態Blazor and shared state

Blazor サーバー アプリはサーバー メモリに存在します。Blazor server apps live in server memory. これは、同じプロセス内で複数のアプリがホストされていることを意味します。That means that there are multiple apps hosted within the same process. Blazor では各アプリ セッションに対して、独自の DI コンテナー スコープで回線が開始されます。For each app session, Blazor starts a circuit with its own DI container scope. つまり、スコープが指定されたサービスは、Blazor セッションごとに一意になるということです。That means that scoped services are unique per Blazor session.

警告

特別な注意を払っていない限り、同じサーバーの共有状態のアプリがシングルトン サービスを使用することはお勧めできません。これにより、回線をまたいだユーザー状態のリークなど、セキュリティ上の脆弱性が生じる可能性があります。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.

Blazor アプリでは、ステートフル シングルトン サービスを使用できます (特に専用に設計されている場合)。You can use stateful singleton services in Blazor apps if they are specifically designed for it. たとえば、メモリ キャッシュをシングルトンとして使用するのは問題ありません。これは、使用されるキャッシュ キーをユーザーが制御できない場合に、特定のエントリにアクセスするためにキーが必要になるためです。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.

また、セキュリティ上の理由から、Blazor アプリ内で IHttpContextAccessor を使用することはできません。Additionally, again for security reasons, you must not use IHttpContextAccessor within Blazor apps. Blazor アプリは、ASP.NET Core パイプラインのコンテキストの外部で実行されます。Blazor apps run outside of the context of the ASP.NET Core pipeline. HttpContext は、IHttpContextAccessor 内で使用できるとは限りません。また、Blazor アプリが開始されたコンテキストが保持されることも保証されません。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.

Blazor アプリに要求状態を渡す方法としては、アプリの初期レンダリングでルート コンポーネントのパラメーターを使用することをお勧めします。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:

  • Blazor アプリに渡すデータをすべて含むクラスを定義します。Define a class with all the data you want to pass to the Blazor app.
  • その時点で利用可能な HttpContext を使用して、Razor ページからそのデータを設定します。Populate that data from the Razor page using the HttpContext available at that time.
  • ルート コンポーネント (アプリ) へのパラメーターとして Blazor アプリにデータを渡します。Pass the data to the Blazor app as a parameter to the root component (App).
  • アプリに渡されるデータを保持するために、ルート コンポーネントでパラメーターを定義します。Define a parameter in the root component to hold the data being passed to the app.
  • アプリ内のユーザー固有のデータを使用します。または、アプリ全体で使用できるようにそのデータを OnInitializedAsync 内のスコープ サービスにコピーします。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.

詳細およびプログラム例については、「ASP.NET Core Blazor Server のセキュリティに関するその他のシナリオ」を参照してください。For more information and example code, see ASP.NET Core Blazor Server のセキュリティに関するその他のシナリオ.

リソースの枯渇Resource exhaustion

リソースの枯渇は、クライアントがサーバーとやり取りし、サーバーが過剰にリソースを消費する場合に発生する可能性があります。Resource exhaustion can occur when a client interacts with the server and causes the server to consume excessive resources. 過剰なリソースの消費が主に影響するのは次のものです。Excessive resource consumption primarily affects:

サービス拒否 (DoS) 攻撃は、通常、アプリまたはサーバーのリソースを枯渇させようとします。Denial of service (DoS) attacks usually seek to exhaust an app or server's resources. しかし、リソースの枯渇が必ずしもシステムへの攻撃の結果であるとは限りません。However, resource exhaustion isn't necessarily the result of an attack on the system. たとえば、ユーザーの要求が多いことで、有限のリソースが使い果たされる可能性があります。For example, finite resources can be exhausted due to high user demand. DoS については、「サービス拒否 (DoS) 攻撃」のセクションで詳しく説明しています。DoS is covered further in the Denial of service (DoS) attacks section.

データベースやファイル ハンドル (ファイルの読み取りと書き込みに使用される) など、Blazor フレームワークの外部のリソースでも、リソースの枯渇が発生する可能性があります。Resources external to the Blazor framework, such as databases and file handles (used to read and write files), may also experience resource exhaustion. 詳細については、「ASP.NET Core パフォーマンスのベストプラクティス」を参照してください。For more information, see ASP.NET Core パフォーマンスのベストプラクティス.

CPUCPU

CPU の枯渇は、1 つ以上のクライアントが大量の CPU 処理を実行するようサーバーに強制した場合に発生する可能性があります。CPU exhaustion can occur when one or more clients force the server to perform intensive CPU work.

例として、"フィボナッチ数" を計算する Blazor Server アプリを考えてみましょう。For example, consider a Blazor Server app that calculates a Fibonnacci number. フィボナッチ数は、フィボナッチ数列から生成されます。この数列の各数は、先行する 2 つの数の合計です。A Fibonnacci number is produced from a Fibonnacci sequence, where each number in the sequence is the sum of the two preceding numbers. 答えに達するまでに必要な作業量は、数列の長さと初期値のサイズによって異なります。The amount of work required to reach the answer depends on the length of the sequence and the size of the initial value. アプリでクライアントの要求に制限を設けていない場合、CPU 負荷の高い計算によって CPU の時間が占有され、他のタスクのパフォーマンスが低下する可能性があります。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. 過剰なリソース消費は、可用性に影響を与えるセキュリティ上の懸念事項です。Excessive resource consumption is a security concern impacting availability.

CPU の枯渇は、すべての公開アプリに関する懸念事項です。CPU exhaustion is a concern for all public-facing apps. 通常の Web アプリでは、セーフガードとして要求と接続がタイムアウトになりますが、Blazor Server アプリには同じセーフガードが用意されていません。In regular web apps, requests and connections time out as a safeguard, but Blazor Server apps don't provide the same safeguards. CPU を集中的に使用する作業を実行する前に、Blazor Server アプリに適切なチェックと制限を含める必要があります。Blazor Server apps must include appropriate checks and limits before performing potentially CPU-intensive work.

メモリMemory

メモリの枯渇は、1 つ以上のクライアントが大量のメモリを消費するようサーバーに強制した場合に発生する可能性があります。Memory exhaustion can occur when one or more clients force the server to consume a large amount of memory.

例として、項目のリストを受け入れて表示するコンポーネントがある Blazor サーバー側アプリについて考えてみましょう。For example, consider a Blazor-server side app with a component that accepts and displays a list of items. Blazor アプリで許可される項目の数またはクライアントにレンダリングされる項目の数が制限されていない場合、メモリを集中的に使用する処理とレンダリングで、サーバーのメモリが占有され、パフォーマンスが低下する可能性があります。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. サーバーがクラッシュしたり、クラッシュしたかのように遅くなったりする場合があります。The server may crash or slow to the point that it appears to have crashed.

サーバー上のメモリの枯渇のシナリオに関連する項目のリストを保持および表示するために、次のシナリオを検討してください。Consider the following scenario for maintaining and displaying a list of items that pertain to a potential memory exhaustion scenario on the server:

  • List<MyItem> プロパティまたはフィールドの項目は、サーバーのメモリを使用します。The items in a List<MyItem> property or field use the server's memory. アプリで項目のリストを無制限に拡張することが許可されていると、サーバーでメモリが不足する危険性があります。If the app allows the list of items to grow unbounded, there's a risk of the server running out of memory. メモリが不足すると、現在のセッションが終了 (クラッシュ) し、そのサーバー インスタンス内のすべての同時セッションでメモリ不足の例外が発生します。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. このシナリオが発生しないようにするには、同時ユーザーに項目の制限を課すデータ構造をアプリで使用する必要があります。To prevent this scenario from occurring, the app must use a data structure that imposes an item limit on concurrent users.
  • レンダリングにページング スキームが使用されていない場合、サーバーにより、UI に表示されないオブジェクトに対して追加のメモリが使用されます。If a paging scheme isn't used for rendering, the server uses additional memory for objects that aren't visible in the UI. 項目の数に制限がないと、メモリの需要によって使用可能なサーバー メモリが枯渇する可能性があります。Without a limit on the number of items, memory demands may exhaust the available server memory. このシナリオを回避するには、次のいずれかの方法を使用します。To prevent this scenario, use one of the following approaches:
    • レンダリング時にページ分割されたリストを使用します。Use paginated lists when rendering.
    • 最初の 100 から 1,000 項目のみを表示し、表示された項目以外の項目を検索するには、検索条件を入力するようユーザーに求めます。Only display the first 100 to 1,000 items and require the user to enter search criteria to find items beyond the items displayed.
    • より高度なレンダリング シナリオでは、"仮想化" をサポートするリストまたはグリッドを実装します。For a more advanced rendering scenario, implement lists or grids that support virtualization. 仮想化を使用すると、リストには、現在ユーザーに表示されている項目のサブセットのみがレンダリングされます。Using virtualization, lists only render a subset of items currently visible to the user. ユーザーが UI のスクロールバーを操作すると、コンポーネントでは表示に必要な項目だけがレンダリングされます。When the user interacts with the scrollbar in the UI, the component renders only those items required for display. 現時点で、表示に必要ない項目は、セカンダリ ストレージに保持できます。これが理想的な方法です。The items that aren't currently required for display can be held in secondary storage, which is the ideal approach. 表示されていない項目をメモリに保持することもできますが、これはあまり理想的ではありません。Undisplayed items can also be held in memory, which is less ideal.

Blazor Server アプリには、WPF、Windows フォーム、Blazor WebAssembly など、ステートフル アプリ用の他の UI フレームワークと同様のプログラミング モデルが用意されています。Blazor Server apps offer a similar programming model to other UI frameworks for stateful apps, such as WPF, Windows Forms, or Blazor WebAssembly. 主な違いは、いくつかの UI フレームワークでは、アプリによって消費されるメモリがクライアントに属し、その個々のクライアントのみに影響することです。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. たとえば、Blazor WebAssembly アプリは、完全にクライアント上で実行され、クライアントのメモリ リソースのみが使用されます。For example, a Blazor WebAssembly app runs entirely on the client and only uses client memory resources. Blazor Server のシナリオでは、アプリによって消費されるメモリは、サーバーに属し、サーバー インスタンス上のクライアント間で共有されます。In the Blazor Server scenario, the memory consumed by the app belongs to the server and is shared among clients on the server instance.

サーバー側のメモリ要求は、すべての Blazor Server アプリにとっての考慮事項です。Server-side memory demands are a consideration for all Blazor Server apps. ただし、ほとんどの Web アプリはステートレスであり、要求の処理中に使用されたメモリは、応答が返されると解放されます。However, most web apps are stateless, and the memory used while processing a request is released when the response is returned. 一般的な推奨事項として、クライアント接続を保持する他のサーバー側アプリと同じように、クライアントが解放されているメモリ容量を割り当てられないようにしてください。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. Blazor Server アプリによって消費されるメモリは、1 つの要求よりも長い時間保持されます。The memory consumed by a Blazor Server app persists for a longer time than a single request.

注意

開発中は、プロファイラーを使用したり、トレースをキャプチャしてクライアントのメモリ要求を評価したりすることができます。During development, a profiler can be used or a trace captured to assess memory demands of clients. プロファイラーまたはトレースでは、特定のクライアントに割り当てられたメモリはキャプチャされません。A profiler or trace won't capture the memory allocated to a specific client. 開発時に特定のクライアントのメモリ使用量をキャプチャするには、ダンプをキャプチャし、ユーザーの回線をルートとするすべてのオブジェクトのメモリ要求を調べます。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.

クライアント接続Client connections

接続の枯渇は、1 つ以上のクライアントがサーバーへのコンカレント接続を多数開いていて、他のクライアントが新しい接続を確立できない場合に発生する可能性があります。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 クライアントは、セッションごとに 1 つの接続を確立し、ブラウザー ウィンドウが開いている間は接続を開いたままにします。Blazor clients establish a single connection per session and keep the connection open for as long as the browser window is open. すべての接続を維持するサーバーに対する要求は、Blazor アプリに固有のものではありません。The demands on the server of maintaining all of the connections isn't specific to Blazor apps. 接続の永続的な性質と Blazor Server アプリのステートフルな性質を考えると、接続の枯渇はアプリの可用性に対するリスクが高くなります。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.

既定では、Blazor Server アプリのユーザーあたりの接続数に制限はありません。By default, there's no limit on the number of connections per user for a Blazor Server app. アプリで接続制限が必要な場合は、次の方法の 1 つまたは複数を実行します。If the app requires a connection limit, take one or more of the following approaches:

  • 認証を要求します。これにより、承認されていないユーザーがアプリに接続する能力が自然に制限されます。Require authentication, which naturally limits the ability of unauthorized users to connect to the app. このシナリオを有効にするには、ユーザーが新しいユーザーを自由にプロビジョニングできないようにする必要があります。For this scenario to be effective, users must be prevented from provisioning new users at will.
  • ユーザーあたりの接続数を制限します。Limit the number of connections per user. 接続の制限は、次の方法で実現できます。Limiting connections can be accomplished via the following approaches. 正当なユーザーにアプリへのアクセスを許可するようにご注意ください (たとえば、クライアントの IP アドレスに基づいて接続の制限が確立されている場合)。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).
    • アプリ レベル:At the app level:

      • エンドポイント ルーティングの拡張性。Endpoint routing extensibility.
      • アプリに接続し、ユーザーごとにアクティブなセッションを追跡するには、認証を要求する。Require authentication to connect to the app and keep track of the active sessions per user.
      • 制限に達したら新しいセッションを拒否する。Reject new sessions upon reaching a limit.
      • プロキシを使用したアプリへのプロキシ WebSocket 接続 (クライアントからアプリへの接続を多重化する Azure SignalR Service など)。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. これにより、1 つのクライアントで確立できるよりも多くの接続容量がアプリに提供されるため、クライアントがサーバーへの接続を使い果たすことを防ぐことができます。This provides an app with greater connection capacity than a single client can establish, preventing a client from exhausting the connections to the server.
    • サーバー レベル: アプリの前にプロキシ/ゲートウェイを使用します。At the server level: Use a proxy/gateway in front of the app. たとえば Azure Front Door を使用すると、アプリへの Web トラフィックのグローバルなルーティングを定義、管理、監視することができ、Blazor Server アプリがロング ポーリングを使用するように構成されている場合に機能します。For example, Azure Front Door enables you to define, manage, and monitor the global routing of web traffic to an app and works when Blazor Server apps are configured to use Long Polling.

      注意

      ロング ポーリングは Blazor Server アプリ用にサポートされていますが、WebSocket が推奨されるトランスポート プロトコルです。Although Long Polling is supported for Blazor Server apps, WebSockets is the recommended transport protocol. 現時点では、Azure Front Door では WebSocket はサポートされていませんが、WebSocket のサポートは今後のサービスのリリースに向けて検討中です。Azure Front Door doesn't support WebSockets at this time, but support for WebSockets is under consideration for a future release of the service.

サービス拒否 (DoS) 攻撃Denial of service (DoS) attacks

サービス拒否 (DoS) 攻撃では、クライアントがサーバーにそのリソースを 1 つ以上使い果たさせることで、アプリを利用できなくします。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 アプリには既定の制限がいくつかあり、CircuitOptions で設定された DoS 攻撃から保護するために、他の ASP.NET Core や SignalR の制限に依存しています。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 アプリの制限Blazor Server app limit 説明Description DefaultDefault
DisconnectedCircuitMaxRetained 特定のサーバーが一度にメモリに保持する切断された回線の最大数。Maximum number of disconnected circuits that a given server holds in memory at a time. 100100
DisconnectedCircuitRetentionPeriod 切断された回線が破棄されるまでにメモリに保持される最大時間。Maximum amount of time a disconnected circuit is held in memory before being torn down. 3 分3 minutes
JSInteropDefaultCallTimeout 非同期の JavaScript 関数呼び出しがタイムアウトするまでにサーバーが待機する最大時間。Maximum amount of time the server waits before timing out an asynchronous JavaScript function invocation. 1 分1 minute
MaxBufferedUnacknowledgedRenderBatches 堅牢な再接続をサポートするために、サーバーが一定期間、メモリに保持する回線あたりの未確認のレンダリング バッチの最大数。Maximum number of unacknowledged render batches the server keeps in memory per circuit at a given time to support robust reconnection. 制限に達すると、クライアントによって 1 つ以上のバッチが確認されるまで、サーバーは新しいレンダリング バッチの生成を停止します。After reaching the limit, the server stops producing new render batches until one or more batches have been acknowledged by the client. 1010

HubConnectionContextOptions を使用して、単一の受信ハブ メッセージの最大メッセージ サイズを設定します。Set the maximum message size of a single incoming hub message with HubConnectionContextOptions.

SignalR および ASP.NET Core の制限SignalR and ASP.NET Core limit 説明Description DefaultDefault
HubConnectionContextOptions.MaximumReceiveMessageSize 個々のメッセージのメッセージ サイズ。Message size for an individual message. 32 KB32 KB

ブラウザー (クライアント) との対話Interactions with the browser (client)

クライアントは、JS 相互運用イベントのディスパッチとレンダリングの完了を通じてサーバーと対話します。A client interacts with the server through JS interop event dispatching and render completion. JS 相互運用通信は、JavaScript と .NET の間で双方向に行われます。JS interop communication goes both ways between JavaScript and .NET:

  • ブラウザー イベントは、非同期方式でクライアントからサーバーにディスパッチされます。Browser events are dispatched from the client to the server in an asynchronous fashion.
  • サーバーは、必要に応じて UI を非同期に再レンダリングして応答します。The server responds asynchronously rerendering the UI as necessary.

.NET から呼び出される JavaScript 関数JavaScript functions invoked from .NET

.NET メソッドから JavaScript への呼び出しの場合:For calls from .NET methods to JavaScript:

  • すべての呼び出しには、構成可能なタイムアウトがあり、失敗すると、呼び出し元に OperationCanceledException が返されます。All invocations have a configurable timeout after which they fail, returning a OperationCanceledException to the caller.
  • JavaScript 呼び出しの結果は信頼できません。The result of a JavaScript call can't be trusted. ブラウザーで実行されている Blazor アプリ クライアントは、呼び出す JavaScript 関数を検索します。The Blazor app client running in the browser searches for the JavaScript function to invoke. 関数が呼び出され、結果またはエラーのいずれかが生成されます。The function is invoked, and either the result or an error is produced. 悪意のあるクライアントは次のことを試みる可能性があります。A malicious client can attempt to:
    • JavaScript 関数からエラーを返すことによって、アプリで問題を発生させる。Cause an issue in the app by returning an error from the JavaScript function.
    • JavaScript 関数から予期しない結果を返すことによって、サーバーで意図しない動作を誘発させる。Induce an unintended behavior on the server by returning an unexpected result from the JavaScript function.

上記のシナリオを防止するために、次の予防措置を講じてください。Take the following precautions to guard against the preceding scenarios:

  • 呼び出し中に発生する可能性のあるエラーを考慮するために、try-catch ステートメント内に JS 相互運用呼び出しをラップします。Wrap JS interop calls within try-catch statements to account for errors that might occur during the invocations. 詳細については、「ASP.NET Core Blazor アプリのエラーを処理する」を参照してください。For more information, see ASP.NET Core Blazor アプリのエラーを処理する.
  • アクションを実行する前に、JS 相互運用の呼び出しから返されたデータ (エラー メッセージを含む) を検証します。Validate data returned from JS interop invocations, including error messages, before taking any action.

ブラウザーから呼び出される .NET メソッド.NET methods invoked from the browser

JavaScript から .NET メソッドへの呼び出しを信頼しないでください。Don't trust calls from JavaScript to .NET methods. .NET メソッドが JavaScript に公開されている場合は、.NET メソッドの呼び出し方法を検討してください。When a .NET method is exposed to JavaScript, consider how the .NET method is invoked:

  • JavaScript に公開されているすべての .NET メソッドは、アプリのパブリック エンドポイントと同様に扱います。Treat any .NET method exposed to JavaScript as you would a public endpoint to the app.
    • 入力を検証します。Validate input.
      • 値が想定される範囲内であることを確認します。Ensure that values are within expected ranges.
      • ユーザーが要求された操作を実行するアクセス許可を持っていることを確認します。Ensure that the user has permission to perform the action requested.
    • .NET メソッドの呼び出しの一部として、過剰な量のリソースを割り当てないでください。Don't allocate an excessive quantity of resources as part of the .NET method invocation. たとえば、チェックを実行し、CPU とメモリの使用量に制限を設けます。For example, perform checks and place limits on CPU and memory use.
    • 静的メソッドとインスタンス メソッドは JavaScript クライアントに公開できることを考慮してください。Take into account that static and instance methods can be exposed to JavaScript clients. 設計で適切な制約を使用して状態の共有を行う必要がある場合を除き、セッション間で状態を共有しないでください。Avoid sharing state across sessions unless the design calls for sharing state with appropriate constraints.
      • 依存関係の挿入 (DI) によって最初に作成された DotNetReference オブジェクトを介して公開されるインスタンス メソッドの場合、オブジェクトはスコープ付きオブジェクトとして登録する必要があります。For instance methods exposed through DotNetReference objects that are originally created through dependency injection (DI), the objects should be registered as scoped objects. これは、Blazor Server アプリが使用するすべての DI サービスに適用されます。This applies to any DI service that the Blazor Server app uses.
      • 静的メソッドの場合は、アプリが明示的にサーバー インスタンス上のすべてのユーザー間で状態を明示的に共有している場合を除き、クライアントにスコープを設定できない状態を確立しないようにしてください。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.
    • ユーザーが指定したデータをパラメーターで JavaScript の呼び出しに渡さないでください。Avoid passing user-supplied data in parameters to JavaScript calls. どうしてもパラメーターでデータを渡す必要がある場合は、クロスサイト スクリプティング (XSS) の脆弱性を取り込むことなく、JavaScript コードでデータの引き渡しを処理できるようにします。If passing data in parameters is absolutely required, ensure that the JavaScript code handles passing the data without introducing Cross-site scripting (XSS) vulnerabilities. たとえば、要素の innerHTML プロパティを設定することによって、ユーザー指定のデータをドキュメント オブジェクト モデル (DOM) に書き込まないようにしてください。For example, don't write user-supplied data to the Document Object Model (DOM) by setting the innerHTML property of an element. コンテンツ セキュリティ ポリシー (CSP) を使用して、eval およびその他の安全でない JavaScript プリミティブを無効にすることを検討してください。Consider using Content Security Policy (CSP) to disable eval and other unsafe JavaScript primitives.
  • フレームワークのディスパッチ実装の上に .NET 呼び出しのカスタム ディスパッチを実装しないでください。Avoid implementing custom dispatching of .NET invocations on top of the framework's dispatching implementation. ブラウザーに .NET メソッドを公開することは高度なシナリオであるため、一般的な Blazor 開発にはお勧めしません。Exposing .NET methods to the browser is an advanced scenario, not recommended for general Blazor development.

イベントEvents

イベントは、Blazor Server アプリへのエントリ ポイントを提供します。Events provide an entry point to a Blazor Server app. Web アプリでエンドポイントを保護する場合と同じ規則が、Blazor Server アプリのイベント処理に適用されます。The same rules for safeguarding endpoints in web apps apply to event handling in Blazor Server apps. 悪意のあるクライアントが、イベントのペイロードとして送信したい任意のデータを送信する可能性があります。A malicious client can send any data it wishes to send as the payload for an event.

次に例を示します。For example:

  • <select> の変更イベントでは、アプリがクライアントに提示したオプションに含まれていない値が送信されることがあります。A change event for a <select> could send a value that isn't within the options that the app presented to the client.
  • <input> は、クライアント側の検証をバイパスして、テキスト データをサーバーに送信することがあります。An <input> could send any text data to the server, bypassing client-side validation.

アプリが処理する任意のイベントのデータをアプリで検証する必要があります。The app must validate the data for any event that the app handles. Blazor フレームワークのフォーム コンポーネントでは、基本的な検証が実行されます。The Blazor framework forms components perform basic validations. アプリでカスタム フォーム コンポーネントを使用する場合は、必要に応じてカスタム コードを記述してイベント データを検証する必要があります。If the app uses custom forms components, custom code must be written to validate event data as appropriate.

Blazor Server イベントは非同期であるため、アプリが新しいレンダリングを生成することによって反応するまでに、複数のイベントをサーバーにディスパッチすることができます。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. これには、考慮すべきセキュリティへの影響がいくつかあります。This has some security implications to consider. アプリでのクライアント アクションの制限は、イベント ハンドラー内で実行する必要があり、現在レンダリングされているビュー状態に依存してはいけません。Limiting client actions in the app must be performed inside event handlers and not depend on the current rendered view state.

ユーザーがカウンターを最大 3 回インクリメントできるようにするカウンター コンポーネントを考えてみましょう。Consider a counter component that should allow a user to increment a counter a maximum of three times. カウンターをインクリメントするボタンは、条件付きで 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++;
    }
}

クライアントは、フレームワークがこのコンポーネントの新しいレンダリングを生成する前に、1 つ以上のインクリメント イベントをディスパッチできます。A client can dispatch one or more increment events before the framework produces a new render of this component. その結果、UI によってすぐにボタンが削除されないため、ユーザーは count を "3 回以上" インクリメントできます。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. 3 回の count のインクリメントの制限を実現するための正しい方法を次の例で示します。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++;
        }
    }
}

ハンドラー内に if (count < 3) { ... } チェックを追加することによって、count をインクリメントするかどうかは、現在のアプリの状態に基づいて決定されます。By adding the if (count < 3) { ... } check inside the handler, the decision to increment count is based on the current app state. この決定は、前の例とは異なり、一時的に古くなっている可能性がある UI の状態に基づいていません。The decision isn't based on the state of the UI as it was in the previous example, which might be temporarily stale.

複数のディスパッチに対するガードGuard against multiple dispatches

イベント コールバックによって、長時間実行される操作 (外部サービスまたはデータベースからのデータのフェッチなど) が非同期に呼び出される場合は、ガードの使用を検討してください。If an event callback invokes a long running operation asynchronously, such as fetching data from an external service or database, consider using a guard. ガードを使用すると、視覚的なフィードバックを使用して、操作の進行中に、ユーザーが複数の操作をキューに入れることを防ぐことができます。The guard can prevent the user from queueing up multiple operations while the operation is in progress with visual feedback. 次のコンポーネント コードでは、GetForecastAsync がサーバーからデータを取得する間に、isLoadingtrue に設定します。The following component code sets isLoading to true while GetForecastAsync obtains data from the server. isLoadingtrue の間は、このボタンは UI では無効になります。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;
        }
    }
}

前の例で示したガード パターンは、バックグラウンド操作が async-await パターンで非同期に実行される場合に機能します。The guard pattern demonstrated in the preceding example works if the background operation is executed asynchronously with the async-await pattern.

早期にキャンセルして、破棄後の使用を回避するCancel early and avoid use-after-dispose

コンポーネントが破棄される場合は、「複数のディスパッチに対するガード」セクションで説明したガードの使用に加えて、CancellationToken を使用して長時間実行される操作を取り消すことを検討してください。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. このアプローチには、コンポーネントで "破棄後の使用" を回避するという追加の利点があります。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();
    }
}

大量のデータを生成するイベントを回避するAvoid events that produce large amounts of data

oninputonscroll などの一部の DOM イベントでは、大量のデータが生成される可能性があります。Some DOM events, such as oninput or onscroll, can produce a large amount of data. Blazor サーバー アプリでは、これらのイベントを使用しないようにしてください。Avoid using these events in Blazor server apps.

セキュリティに関するその他のガイダンスAdditional security guidance

ASP.NET Core アプリをセキュリティで保護するためのガイダンスが、Blazor Server アプリに適用されます。詳細については、以降のセクションで説明します。The guidance for securing ASP.NET Core apps apply to Blazor Server apps and are covered in the following sections:

ログ記録と機密データLogging and sensitive data

クライアントとサーバー間の JS 相互運用操作は、ILogger インスタンスと共にサーバーのログに記録されます。JS interop interactions between the client and server are recorded in the server's logs with ILogger instances. Blazor では、実際のイベントや JS 相互運用の入力や出力などの機密情報のログ記録が回避されます。Blazor avoids logging sensitive information, such as actual events or JS interop inputs and outputs.

サーバーでエラーが発生すると、フレームワークによってクライアントに通知され、セッションが破棄されます。When an error occurs on the server, the framework notifies the client and tears down the session. 既定では、クライアントは、ブラウザーの開発者ツールで見られる一般的なエラー メッセージを受け取ります。By default, the client receives a generic error message that can be seen in the browser's developer tools.

クライアント側のエラーには、呼び出し履歴は含まれず、エラーの原因についての詳細は提供されませんが、サーバー ログにはこのような情報が含まれています。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. 開発目的で、詳細なエラーを有効にすることによって、機密性の高いエラー情報をクライアントが利用できるようにすることができます。For development purposes, sensitive error information can be made available to the client by enabling detailed errors.

JavaScript では、以下を使用して詳細なエラーを有効にします。Enable detailed errors in JavaScript with:

  • CircuitOptions.DetailedErrors.CircuitOptions.DetailedErrors.
  • DetailedErrors 構成キーを true に設定します。これはアプリ設定ファイル (appsettings.json) で設定できます。The DetailedErrors configuration key set to true, which can be set in the app settings file (appsettings.json). このキーは、値を true にした ASPNETCORE_DETAILEDERRORS 環境変数を使用することで設定することもできます。The key can also be set using the ASPNETCORE_DETAILEDERRORS environment variable with a value of true.

警告

インターネット上でクライアントにエラー情報を公開することは、常に回避すべきセキュリティ リスクです。Exposing error information to clients on the Internet is a security risk that should always be avoided.

HTTPS を使用した転送中の情報の保護Protect information in transit with HTTPS

Blazor Server では、クライアントとサーバー間の通信に SignalR が使用されます。Blazor Server uses SignalR for communication between the client and the server. Blazor Server では通常、SignalR がネゴシエートするトランスポート (通常は WebSocket) が使用されます。Blazor Server normally uses the transport that SignalR negotiates, which is typically WebSockets.

Blazor Server では、サーバーとクライアントの間で送信されるデータの整合性と機密性は保証されません。Blazor Server doesn't ensure the integrity and confidentiality of the data sent between the server and the client. 常に HTTPS を使用します。Always use HTTPS.

クロスサイト スクリプティング (XSS)Cross-site scripting (XSS)

クロスサイトス クリプティング (XSS) を使用すると、承認されていないパーティが、ブラウザーのコンテキストで任意のロジックを実行することができます。Cross-site scripting (XSS) allows an unauthorized party to execute arbitrary logic in the context of the browser. 侵害されたアプリが、クライアントで任意のコードを実行する可能性があります。A compromised app could potentially run arbitrary code on the client. 脆弱性を利用して、サーバーに対して多くの悪意のある操作が実行される可能性があります。The vulnerability could be used to potentially perform a number of malicious actions against the server:

  • 偽のイベントや無効なイベントをサーバーにディスパッチする。Dispatch fake/invalid events to the server.
  • 失敗または無効なレンダリング完了をディスパッチする。Dispatch fail/invalid render completions.
  • レンダリング完了のディスパッチを回避する。Avoid dispatching render completions.
  • JavaScript から相互運用呼び出しを .NET にディスパッチする。Dispatch interop calls from JavaScript to .NET.
  • .NET から JavaScript への相互運用呼び出しの応答を変更する。Modify the response of interop calls from .NET to JavaScript.
  • JS 相互運用の結果に .NET をディスパッチすることを回避する。Avoid dispatching .NET to JS interop results.

Blazor Server フレームワークでは、前述のいくつかの脅威から保護するためのステップが実行されます。The Blazor Server framework takes steps to protect against some of the preceding threats:

  • クライアントがレンダリング バッチを確認していない場合は、新しい UI 更新の生成を停止します。Stops producing new UI updates if the client isn't acknowledging render batches. CircuitOptions.MaxBufferedUnacknowledgedRenderBatches で構成されます。Configured with CircuitOptions.MaxBufferedUnacknowledgedRenderBatches.
  • クライアントからの応答を受信せずに、1 分後に .NET から JavaScript への呼び出しをタイムアウトにします。Times out any .NET to JavaScript call after one minute without receiving a response from the client. CircuitOptions.JSInteropDefaultCallTimeout で構成されます。Configured with CircuitOptions.JSInteropDefaultCallTimeout.
  • JS 相互運用中にブラウザーからのすべての入力に対して、次の基本的な検証を実行します。Performs basic validation on all input coming from the browser during JS interop:
    • .NET 参照は有効であり、.NET メソッドで予期される型であること。.NET references are valid and of the type expected by the .NET method.
    • データが不正な形式ではないこと。The data isn't malformed.
    • メソッドの正しい数の引数がペイロードに存在していること。The correct number of arguments for the method are present in the payload.
    • メソッドを呼び出す前に、引数または結果が正しく逆シリアル化できること。The arguments or result can be deserialized correctly before invoking the method.
  • 次に示すディスパッチされたイベントから、ブラウザーからのすべての入力に対して、次の基本的な検証を実行します。Performs basic validation in all input coming from the browser from dispatched events:
    • イベントに有効な型があること。The event has a valid type.
    • イベントのデータを逆シリアル化できること。The data for the event can be deserialized.
    • イベントに関連付けられているイベント ハンドラーがあること。There's an event handler associated with the event.

脅威から保護し、適切なアクションを実行するには、フレームワークが実装するセーフガードに加えて、アプリが開発者によってコーディングされている必要があります。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:

  • イベントを処理するときは常にデータを検証します。Always validate data when handling events.
  • 無効なデータの受信時に適切なアクションを実行します。Take appropriate action upon receiving invalid data:
    • データを無視して戻ります。Ignore the data and return. これにより、アプリは要求の処理を続行できます。This allows the app to continue processing requests.
    • アプリは、入力が不正であり、正当なクライアントによって生成されたものではないと判断すると、例外をスローします。If the app determines that the input is illegitimate and couldn't be produced by legitimate client, throw an exception. 例外をスローすると、回線が破棄され、セッションが終了します。Throwing an exception tears down the circuit and ends the session.
  • ログに含まれるレンダリング バッチの完了によって提供されるエラー メッセージは信頼しないでください。Don't trust the error message provided by render batch completions included in the logs. このエラーはクライアントによって提供され、クライアントが侵害されている可能性があるため、通常は信頼できません。The error is provided by the client and can't generally be trusted, as the client might be compromised.
  • JavaScript と .NET メソッドの間では、どちらの方向でも JS 相互運用呼び出しの入力を信頼しないでください。Don't trust the input on JS interop calls in either direction between JavaScript and .NET methods.
  • 引数または結果が正しく逆シリアル化された場合でも、引数と結果の内容が有効であることを検証するのはアプリの役割です。The app is responsible for validating that the content of arguments and results are valid, even if the arguments or results are correctly deserialized.

XSS の脆弱性が存在するには、アプリがレンダリングされたページにユーザー入力を組み込む必要があります。For a XSS vulnerability to exist, the app must incorporate user input in the rendered page. Blazor Server コンポーネントでは、.razor ファイルのマークアップが手続き型 C# ロジックに変換されるコンパイル時のステップが実行されます。Blazor Server components execute a compile-time step where the markup in a .razor file is transformed into procedural C# logic. 実行時に、C# ロジックによって、要素、テキスト、および子コンポーネントを記述する "レンダリング ツリー" が構築されます。At runtime, the C# logic builds a render tree describing the elements, text, and child components. これは、JavaScript 命令のシーケンスを通じてブラウザーの DOM に適用されます (または、プリレンダリングの場合は HTML にシリアル化されます)。This is applied to the browser's DOM via a sequence of JavaScript instructions (or is serialized to HTML in the case of prerendering):

  • 通常の Razor 構文 (@someStringValue など) を使用してレンダリングされたユーザー入力では、XSS 脆弱性は公開されません。これは、Razor 構文が、テキストのみを書き込むことができるコマンドを使用して DOM に追加されるためです。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. 値に HTML マークアップが含まれている場合でも、値は静的なテキストとして表示されます。Even if the value includes HTML markup, the value is displayed as static text. プリレンダリング時に、出力は HTML エンコードされ、コンテンツも静的テキストとして表示されます。When prerendering, the output is HTML-encoded, which also displays the content as static text.
  • スクリプト タグは許可されていないため、アプリのコンポーネント レンダリング ツリーに含めることはできません。Script tags aren't allowed and shouldn't be included in the app's component render tree. コンポーネントのマークアップにスクリプト タグが含まれていると、コンパイル時のエラーが生成されます。If a script tag is included in a component's markup, a compile-time error is generated.
  • コンポーネントの作成者は、Razor を使用せずに C# でコンポーネントを作成できます。Component authors can author components in C# without using Razor. コンポーネントの作成者は、出力の生成時に適切な API を使用する必要があります。The component author is responsible for using the correct APIs when emitting output. たとえば、builder.AddContent(0, someUserSuppliedString) を使用します。builder.AddMarkupContent(0, someUserSuppliedString) は使用 "しないでください"。後者では XSS 脆弱性が生成される可能性があります。For example, use builder.AddContent(0, someUserSuppliedString) and not builder.AddMarkupContent(0, someUserSuppliedString), as the latter could create a XSS vulnerability.

XSS 攻撃からの保護の一環として、コンテンツ セキュリティ ポリシー (CSP) などの XSS 軽減策を実装することを検討してください。As part of protecting against XSS attacks, consider implementing XSS mitigations, such as Content Security Policy (CSP).

詳細については、「ASP.NET Core でクロスサイトスクリプティング (XSS) を防止する」を参照してください。For more information, see ASP.NET Core でクロスサイトスクリプティング (XSS) を防止する.

クロスオリジン保護Cross-origin protection

クロスオリジン攻撃では、サーバーに対してアクションを実行する別のオリジンのクライアントが関与します。Cross-origin attacks involve a client from a different origin performing an action against the server. 悪意のあるアクションは通常、GET 要求またはフォーム POST (クロスサイト リクエスト フォージェリ (CSRF)) ですが、悪意のある WebSocket を開くことも可能です。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 アプリでは、ハブ プロトコルを使用する他の SignalR アプリが提供するのと同じ保証を提供します。Blazor Server apps offer the same guarantees that any other SignalR app using the hub protocol offer:

  • クロスオリジンを防ぐ追加の手段を講じない限り、Blazor Server アプリにアクセスされる可能性があります。Blazor Server apps can be accessed cross-origin unless additional measures are taken to prevent it. クロスオリジンのアクセスを無効にするには、CORS ミドルウェアをパイプラインに追加し、DisableCorsAttribute を Blazor エンドポイント メタデータに追加することによって、エンドポイントで CORS を無効にするか、クロスオリジン リソース共有に SignalR を構成することによって、許可されるオリジンのセットを制限します。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.
  • CORS が有効になっている場合、CORS の構成によっては、アプリを保護するために追加のステップが必要になることがあります。If CORS is enabled, extra steps might be required to protect the app depending on the CORS configuration. CORS がグローバルに有効になっている場合、Blazor Server ハブに対する CORS を無効にするには、エンドポイント ルート ビルダーで MapBlazorHub を呼び出した後、エンドポイントのメタデータに DisableCorsAttribute メタデータを追加します。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.

詳細については、「ASP.NET Core でのクロスサイト要求偽造 (XSRF/CSRF) 攻撃を防ぐ」を参照してください。For more information, see ASP.NET Core でのクロスサイト要求偽造 (XSRF/CSRF) 攻撃を防ぐ.

クリック ジャッキングClick-jacking

クリック ジャッキングでは、ユーザーをだまして攻撃を受けているサイトでアクションを実行させるために、サイトを異なるオリジンのサイト内の <iframe> としてレンダリングします。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.

<iframe> 内でのレンダリングからアプリを保護するには、コンテンツ セキュリティ ポリシー (CSP)X-Frame-Options ヘッダーを使用します。To protect an app from rendering inside of an <iframe>, use Content Security Policy (CSP) and the X-Frame-Options header. 詳細については、MDN Web ドキュメント:X-Frame-Options を参照してください。For more information, see MDN web docs: X-Frame-Options.

オープン リダイレクトOpen redirects

Blazor Server アプリ セッションが開始されると、セッションの開始時に送信される URL の基本的な検証がサーバーによって実行されます。When a Blazor Server app session starts, the server performs basic validation of the URLs sent as part of starting the session. フレームワークでは、回線を確立する前に、ベース URL が現在の URL の親であることが確認されます。The framework checks that the base URL is a parent of the current URL before establishing the circuit. フレームワークでは、追加のチェックは実行されません。No additional checks are performed by the framework.

クライアントでユーザーがリンクを選択すると、リンクの URL がサーバーに送信され、これにより実行するアクションが決まります。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. たとえば、アプリがクライアント側のナビゲーションを実行したり、新しい場所に移動するようにブラウザーに指示したりすることができます。For example, the app may perform a client-side navigation or indicate to the browser to go to the new location.

コンポーネントでも、NavigationManager を使用して、プログラムによってナビゲーション要求をトリガーすることができます。Components can also trigger navigation requests programatically through the use of NavigationManager. このようなシナリオでは、アプリがクライアント側のナビゲーションを実行したり、新しい場所に移動するようにブラウザーに指示したりすることができます。In such scenarios, the app might perform a client-side navigation or indicate to the browser to go to the new location.

コンポーネントでは、次のことを行う必要があります。Components must:

  • ナビゲーション呼び出しの引数の一部としてのユーザー入力の使用を避ける。Avoid using user input as part of the navigation call arguments.
  • 引数を検証して、ターゲットがアプリで許可されていることを保証する。Validate arguments to ensure that the target is allowed by the app.

そうしないと、悪意のあるユーザーが、ブラウザーを攻撃者が制御するサイトに強制的に移動させる可能性があります。Otherwise, a malicious user can force the browser to go to an attacker-controlled site. このシナリオでは、攻撃者はアプリをだまして NavigationManager.NavigateTo メソッドの呼び出しの一部としてユーザー入力を使用させます。In this scenario, the attacker tricks the app into using some user input as part of the invocation of the NavigationManager.NavigateTo method.

このアドバイスは、アプリの一部としてリンクをレンダリングする場合にも当てはまります。This advice also applies when rendering links as part of the app:

  • 可能であれば、相対リンクを使用します。If possible, use relative links.
  • 絶対リンクをページに含める前に、リンク先が有効であることを検証します。Validate that absolute link destinations are valid before including them in a page.

詳細については、「ASP.NET Core でのオープンリダイレクト攻撃の防止」を参照してください。For more information, see ASP.NET Core でのオープンリダイレクト攻撃の防止.

セキュリティ チェックリストSecurity checklist

次のセキュリティの考慮事項のリストは、包括的なものではありません。The following list of security considerations isn't comprehensive:

  • イベントからの引数を検証する。Validate arguments from events.
  • JS 相互運用呼び出しからの入力と結果を検証する。Validate inputs and results from JS interop calls.
  • .NET から JS への相互運用呼び出しに対してユーザー入力を使用しないようにする (または事前に検証する)。Avoid using (or validate beforehand) user input for .NET to JS interop calls.
  • クライアントが、解放されたメモリ容量を割り当てないようにする。Prevent the client from allocating an unbound amount of memory.
    • コンポーネント内のデータ。Data within the component.
    • クライアントに返された DotNetObject 参照。DotNetObject references returned to the client.
  • 複数のディスパッチに対するガード。Guard against multiple dispatches.
  • コンポーネントが破棄されるときに、実行時間の長い操作をキャンセルする。Cancel long-running operations when the component is disposed.
  • 大量のデータを生成するイベントを回避する。Avoid events that produce large amounts of data.
  • NavigationManager.NavigateTo の呼び出しの一部としてユーザー入力を使用することは避け、避けられない場合は、最初に許可されたオリジンのセットに対して URL のユーザー入力を検証する。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.
  • 承認は、UI の状態に基づいてではなく、コンポーネントの状態からのみ判断する。Don't make authorization decisions based on the state of the UI but only from component state.
  • XSS 攻撃から保護するためにコンテンツ セキュリティ ポリシー (CSP) の使用を検討する。Consider using Content Security Policy (CSP) to protect against XSS attacks.
  • クリック ジャッキングから保護するため、CSP と X-Frame-Options の使用を検討する。Consider using CSP and X-Frame-Options to protect against click-jacking.
  • CORS を有効にする場合や Blazor アプリの CORS を明示的に無効にする場合は、CORS 設定が適切であることを確認する。Ensure CORS settings are appropriate when enabling CORS or explicitly disable CORS for Blazor apps.
  • Blazor アプリのサーバー側の制限が、許容できないレベルのリスクなしに、許容できるユーザー エクスペリエンスを提供することを保証するためにテストする。Test to ensure that the server-side limits for the Blazor app provide an acceptable user experience without unacceptable levels of risk.