---
title: "GraphQLのセキュリティ"
slug: "graphql-security"
abstract: "GraphQLの具体的なセキュリティ上の懸念について説明します。"
---
# GraphQLのセキュリティ

GraphQL APIの特定のセキュリティ上の懸念に対処する必要があります。GraphQLサーバーが実行されるため、非常に高コストなクエリを構築し、サービス拒否攻撃を引き起こす可能性があります。この問題は2つの方法で緩和できます。

-   クエリ複雑性分析を使って、データ量が多すぎるクエリは却下します。
-   クエリ深度分析を用いて、深く入れ子にされたクエリを却下します。

これらの緩和策は、任意のクエリが実行される公開APIに対して有効です。自分で制御するクエリのみをサポートするAPIでは、ホワイトリスト化で問題が完全に軽減されます。

> !注複雑度のデフォルト設定は /App\_Config/Sitecore/Services.GraphQL/Sitecore.Services.GraphQL.configで指定されています。

## キャッシュとホワイトリスト

GraphQL APIはSitecoreキャッシュインスタンスを使って、事前解析・検証された入ってくるクエリを保存します。検証が完了すると、クエリは再度検証される必要がなくなり、キャッシュから取得されます。デフォルトのキャッシュサイズは10MBで、各エンドポイントごとにサイズを設定できます。

デフォルトのキャッシュ機構は、Apolloが開発した自動永続検索(APQ)プロトコルのサポートも可能にします。APQクライアントは実行したいクエリのハッシュを送信します。クエリがキャッシュされている場合は、クエリの全内容を送信するのではなく、そのハッシュを使って実行されます。クエリがキャッシュにない場合は特定のエラー返信が送信され、クライアントはクエリテキストとともに再度リクエストを発行し、サーバーが将来の再利用のためにキャッシュできるようにします。この手法は最小限の労力で受信帯域幅を大幅に削減できます。

キャッシュ機構はクエリホワイトリストを利用する方法も提供します。ホワイトリストはサービス拒否攻撃APIからの保護だけでなく、APQと同様に帯域幅の使用削減にもつながります。なぜなら、クエリ全体を送信する必要はなく、クエリへのポインタやハッシュだけを送るからです。GraphQL APIは、許可されるクエリがキャッシュ内のものだけである権威的なキャッシュの概念をサポートしています。 WhitelistingGraphQLQueryCacheクラスは、以下の特徴を持つデフォルトのホワイトリスト実装を提供します。

-   ストアはディスク上のフォルダ内のファイルとしてクエリを可能にしており(ソース管理のコミットを確認するのが容易でした)。
-   アプリ内のクエリを保存するために .graphql ファイルを使って、1ファイルごとに1つのGQL操作を保存すれば、これらのファイルをホワイトリストにコピーできます。
-   受け取ったクエリをホワイトリストファイルに追加する学習モードをサポートしています。これは、ビルド時にアプリケーション内のすべてのクエリを実行するエンドツーエンドテストがある場合に適しています。本番環境では学習モードは無効化されています。
-   保存クエリにはAPQ互換のハッシュを使用しているため、APQクライアントは自動部分なしですべてのAPQ機能を接続し、アクセスできます(実行されたクエリはホワイトリストに載っている必要があります)。
-   ホワイトリストが変更されると再読み込みします。

キャッシュの設定は設定ファイルのエンドポイントに登録されます。カスタムキャッシュ実装はIGraphQLQueryCacheFactoryから継承しなければなりません。以下の例はホワイトリストキャッシュの登録方法を示しています:

<cache type="Sitecore.Services.GraphQL.Hosting.QueryTransformation.Caching.WhitelistingGraphQLQueryCache, Sitecore.Services.GraphQL.NetFxHost">   
 <!-- path can be virtual (/... or ~/...) or physical (c:\\...) -->   
 <param desc="path">~/App\_Data/GraphQL/myendpoint-whitelist</param>
    <param desc="hashFactory">       
 <hashFactory type="Sitecore.Services.GraphQL.Hosting.Hashing.Sha256DocumentHashFactory, Sitecore.Services.GraphQL.NetFxHost"/>   
 </param>   
 <!-- learning allows the whitelist to add incoming queries; then disable this in production -->   
 <learningEnabled>true</learningEnabled>
</cache>
## 認可

GraphQLの認可はビジネスロジック/スキーマレベルで行われます。各リゾルバ関数は特定のグラフノードに対して必要に応じて認可を確認しなければなりません。

API全体でカスタム認可が必要な場合は、<security>セクションで各APIリクエストを認可するためにIAuthorizationFilterベースのクラスを登録できます:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
 <sitecore>
 <api>
 <GraphQL>
 <endpoints>
 <master>
 <security>
 <authorization type="My.Type.Derived.From.IAuthorizationFilter, My.Assembly" />
 </security>
 </master>
 </endpoints>
 </GraphQL>
 </api>
 </sitecore>
</configuration>