Translated ['src/network-services-pentesting/pentesting-web/graphql.md']

This commit is contained in:
Translator 2025-01-22 23:12:37 +00:00
parent bb438c76ad
commit 06ac5c714f

View File

@ -4,7 +4,7 @@
## Introduction ## Introduction
GraphQLは**効率的な代替手段**として**強調されており**、バックエンドからデータをクエリするための簡素化されたアプローチを提供します。RESTとは異なり、RESTはデータを収集するためにさまざまなエンドポイントに対して多数のリクエストを必要とすることが多いですが、GraphQLは**単一のリクエスト**で必要なすべての情報を取得できます。この簡素化は、データ取得プロセスの複雑さを軽減することにより、**開発者に大きな利益をもたらします**。 GraphQLは**効率的な代替手段**として**強調されており**、バックエンドからデータをクエリするための簡素化されたアプローチを提供します。RESTとは異なり、RESTはデータを収集するためにさまざまなエンドポイントに対して多数のリクエストを必要とすることが多いですが、GraphQLは**単一のリクエスト**で必要なすべての情報を取得することを可能にします。この簡素化は、データ取得プロセスの複雑さを軽減することにより、**開発者に大きな利益をもたらします**。
## GraphQLとセキュリティ ## GraphQLとセキュリティ
@ -23,7 +23,7 @@ GraphQLを含む新しい技術の登場に伴い、新しいセキュリティ
- `/graphql/api` - `/graphql/api`
- `/graphql/graphql` - `/graphql/graphql`
オープンなGraphQLインスタンスを特定することで、サポートされているクエリを調査できます。これは、エンドポイントを通じてアクセス可能なデータを理解するために重要です。GraphQLのイントロスペクションシステムは、スキーマがサポートするクエリを詳細に示すことでこれを容易にします。これに関する詳細は、GraphQLのイントロスペクションに関するドキュメントを参照してください[**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/) オープンなGraphQLインスタンスを特定することで、サポートされているクエリを調査することができます。これは、エンドポイントを通じてアクセス可能なデータを理解するために重要です。GraphQLのイントロスペクションシステムは、スキーマがサポートするクエリを詳細に示すことでこれを容易にします。これに関する詳細は、GraphQLのイントロスペクションに関するドキュメントを参照してください[**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/)
### フィンガープリンティング ### フィンガープリンティング
@ -41,7 +41,7 @@ Graphqlは通常、**GET**、**POST** (x-www-form-urlencoded) および **POST**
#### インストロスペクション #### インストロスペクション
スキーマ情報を発見するためにインストロスペクションを使用するには、`__schema`フィールドをクエリします。このフィールドはすべてのクエリのルートタイプで利用可能です。 スキーマ情報を発見するためにインストロスペクションを使用するには、`__schema`フィールドをクエリします。このフィールドはすべてのクエリのルートタイプで利用可能です。
```bash ```bash
query={__schema{types{name,fields{name}}}} query={__schema{types{name,fields{name}}}}
``` ```
@ -57,7 +57,7 @@ query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofTy
**エラー** **エラー**
**エラー**が**表示**されるかどうかを知ることは興味深いことであり、それは有用な**情報**に貢献します。 **エラー**が**表示**されるかどうかを知ることは興味深いです。これは有用な**情報**に貢献します。
``` ```
?query={__schema} ?query={__schema}
?query={} ?query={}
@ -170,7 +170,7 @@ name
### クエリ ### クエリ
データベースにどのような情報が保存されているかがわかったので、**いくつかの値を抽出してみましょう**。 データベースにどのような情報が保存されているかがわかったので、**いくつかの値を抽出してみましょう**。
イントロスペクションでは、**どのオブジェクトを直接クエリできるか**を見つけることができます(オブジェクトが存在するからといってクエリできるわけではありません)。次の画像では、"_queryType_"が"_Query_"と呼ばれ、"_Query_"オブジェクトのフィールドの1つが"_flags_"であり、これもオブジェクトのタイプであることがわかります。したがって、フラグオブジェクトをクエリできます。 イントロスペクションでは、**どのオブジェクトを直接クエリできるか**を見つけることができます(オブジェクトが存在するからといってクエリできるわけではありません)。次の画像では、"_queryType_"が"_Query_"と呼ばれ、"_Query_"オブジェクトのフィールドの1つが"_flags_"であり、これもオブジェクトのタイプであることがわかります。したがって、フラグオブジェクトをクエリできます。
@ -184,7 +184,11 @@ name
```javascript ```javascript
query={flags{name, value}} query={flags{name, value}}
``` ```
次の例のように、**クエリするオブジェクト**が**文字列**のような**プリミティブ****タイプ**である場合は、次のようにクエリできます。 次の例のように、**クエリするオブジェクト**が**プリミティブ****タイプ**(例えば**文字列**)の場合は、次のようにクエリできます。
![](<../../images/image (958).png>)
次のようにクエリできます:
```javascript ```javascript
query = { hiddenFlags } query = { hiddenFlags }
``` ```
@ -193,14 +197,14 @@ query = { hiddenFlags }
![](<../../images/image (880).png>) ![](<../../images/image (880).png>)
しかし、この例ではそうしようとすると、次の **エラー** が発生します: しかし、この例ではそうしようとすると **エラー** が発生します:
![](<../../images/image (1042).png>) ![](<../../images/image (1042).png>)
どうやら、"_**uid**_" 引数のタイプ _**Int**_ を使用して検索するようです。\ どうやら、"_**uid**_" 引数のタイプ _**Int**_ を使用して検索するようです。\
とにかく、[Basic Enumeration](graphql.md#basic-enumeration) セクションで、必要な情報をすべて表示するクエリが提案されていました: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` とにかく、私たちはすでに、[Basic Enumeration](graphql.md#basic-enumeration) セクションで、必要な情報をすべて表示するクエリが提案されていることを知っていました: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
そのクエリを実行したときに提供された画像を読むと、"_**user**_" にタイプ _Int_**arg** "_**uid**_" があることがわかります。 提供された画像を読むと、そのクエリを実行したときに "_**user**_" にタイプ _Int_**arg** "_**uid**_" があったことがわかります。
したがって、軽い _**uid**_ ブルートフォースを実行したところ、_**uid**=**1** でユーザー名とパスワードが取得されました:\ したがって、軽い _**uid**_ ブルートフォースを実行したところ、_**uid**=**1** でユーザー名とパスワードが取得されました:\
`query={user(uid:1){user,password}}` `query={user(uid:1){user,password}}`
@ -279,7 +283,7 @@ name
``` ```
### Mutations ### Mutations
**ミューテーションはサーバーサイドで変更を加えるために使用されます。** **ミューテーションはサーバーで変更を加えるために使用されます。**
**イントロスペクション**では、**宣言された** **ミューテーション**を見つけることができます。次の画像では、"_MutationType_"は"_Mutation_"と呼ばれ、"_Mutation_"オブジェクトにはミューテーションの名前(この場合は"_addPerson_"など)が含まれています: **イントロスペクション**では、**宣言された** **ミューテーション**を見つけることができます。次の画像では、"_MutationType_"は"_Mutation_"と呼ばれ、"_Mutation_"オブジェクトにはミューテーションの名前(この場合は"_addPerson_"など)が含まれています:
@ -330,12 +334,12 @@ releaseYear
``` ```
### ディレクティブのオーバーロード ### ディレクティブのオーバーロード
このレポートで説明されている[**脆弱性のつ**](https://www.landh.tech/blog/20240304-google-hack-50000/)によれば、ディレクティブのオーバーロードは、サーバーが操作を無駄にするまで、ディレクティブを何百万回も呼び出すことを意味します。最終的にはDoS攻撃が可能になります。 このレポートで説明されている[**脆弱性の1つ**](https://www.landh.tech/blog/20240304-google-hack-50000/)によれば、ディレクティブのオーバーロードは、サーバーが操作を無駄にするまで、ディレクティブを何百万回も呼び出すことを意味します。最終的にはDoS攻撃が可能になります。
### 1つのAPIリクエストでのバッチブルートフォース ### 1つのAPIリクエストでのバッチブルートフォース
この情報は[https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/)から取得されました。\ この情報は[https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/)から取得されました。\
**異なる認証情報で多くのクエリを同時に送信する**ことでGraphQL APIを通じて認証を行います。これは古典的なブルートフォース攻撃ですが、GraphQLのバッチ機能により、1つのHTTPリクエストで複数のログイン/パスワードペアを送信することが可能になりました。このアプローチは、外部のレート監視アプリケーションを欺いて、すべてが正常であり、パスワードを推測しようとするブルートフォースボットがいないと考えさせることができます。 **異なる認証情報で多くのクエリを同時に送信する**ことでGraphQL APIを通じて認証を行います。これは古典的なブルートフォース攻撃ですが、GraphQLのバッチ機能により、1つのHTTPリクエストで複数のログイン/パスワードペアを送信することが可能になりました。このアプローチは、外部のレート監視アプリケーションを欺、すべてが正常であり、パスワードを推測しようとするブルートフォースボットがいないと考えさせることができます。
以下は、**同時に3つの異なるメール/パスワードペア**を使用したアプリケーション認証リクエストの最も簡単なデモです。明らかに、同じ方法で1回のリクエストで数千を送信することが可能です 以下は、**同時に3つの異なるメール/パスワードペア**を使用したアプリケーション認証リクエストの最も簡単なデモです。明らかに、同じ方法で1回のリクエストで数千を送信することが可能です
@ -349,7 +353,7 @@ releaseYear
ますます多くの**graphqlエンドポイントがインストロスペクションを無効にしています**。しかし、予期しないリクエストが受信されたときにgraphqlが投げるエラーは、[**clairvoyance**](https://github.com/nikitastupin/clairvoyance)のようなツールがスキーマの大部分を再構築するのに十分です。 ますます多くの**graphqlエンドポイントがインストロスペクションを無効にしています**。しかし、予期しないリクエストが受信されたときにgraphqlが投げるエラーは、[**clairvoyance**](https://github.com/nikitastupin/clairvoyance)のようなツールがスキーマの大部分を再構築するのに十分です。
さらに、Burp Suite拡張機能[**GraphQuail**](https://github.com/forcesunseen/graphquail)は、**Burpを通過するGraphQL APIリクエストを観察し**、新しいクエリを見るたびに内部GraphQL**スキーマ**を**構築**します。また、GraphiQLやVoyager用にスキーマを公開することもできます。この拡張機能は、インストロスペクションクエリを受信すると偽のレスポンスを返します。その結果、GraphQuailはAPI内で使用可能なすべてのクエリ、引数、およびフィールドを表示します。詳細については[**こちらを確認してください**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema)。 さらに、Burp Suite拡張機能[**GraphQuail**](https://github.com/forcesunseen/graphquail)は、**Burpを通過するGraphQL APIリクエストを観察し**、**新しいクエリを見るたびに**内部GraphQL **スキーマ**を構築します。また、GraphiQLやVoyager用にスキーマを公開することもできます。この拡張機能は、インストロスペクションクエリを受信すると偽のレスポンスを返します。その結果、GraphQuailはAPI内で使用可能なすべてのクエリ、引数、およびフィールドを表示します。詳細については[**こちらを確認してください**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema)。
素晴らしい**ワードリスト**は、[**GraphQLエンティティを発見するためにここにあります**](https://github.com/Escape-Technologies/graphql-wordlist?)。 素晴らしい**ワードリスト**は、[**GraphQLエンティティを発見するためにここにあります**](https://github.com/Escape-Technologies/graphql-wordlist?)。
@ -421,7 +425,7 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
ただし、Chromeの`samesite`フラグの新しいデフォルトクッキー値は`Lax`であることに注意してください。これは、クッキーがGETリクエストでのみサードパーティのウェブから送信されることを意味します。 ただし、Chromeの`samesite`フラグの新しいデフォルトクッキー値は`Lax`であることに注意してください。これは、クッキーがGETリクエストでのみサードパーティのウェブから送信されることを意味します。
通常、**クエリ** **リクエスト**を**GET** **リクエスト**として送信することも可能であり、GETリクエストではCSRFトークンが検証されない可能性があることに注意してください **クエリ** **リクエスト**を**GET** **リクエスト**として送信することも通常可能であり、GETリクエストではCSRFトークンが検証されない可能性があります
また、[**XS-Search**](../../pentesting-web/xs-search/index.html) **攻撃**を悪用することで、ユーザーの資格情報を利用してGraphQLエンドポイントからコンテンツを抽出することが可能かもしれません。 また、[**XS-Search**](../../pentesting-web/xs-search/index.html) **攻撃**を悪用することで、ユーザーの資格情報を利用してGraphQLエンドポイントからコンテンツを抽出することが可能かもしれません。
@ -429,7 +433,7 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
## GraphQLにおけるクロスサイトWebSocketハイジャック ## GraphQLにおけるクロスサイトWebSocketハイジャック
GraphQLのCRSF脆弱性を悪用するのと同様に、**保護されていないクッキーを使用してGraphQLでの認証を悪用するためクロスサイトWebSocketハイジャックを実行することも可能です**。これにより、ユーザーがGraphQLで予期しないアクションを実行することになります。 GraphQLのCRSF脆弱性を悪用するのと同様に、**保護されていないクッキーを使用してGraphQLでの認証を悪用するためクロスサイトWebSocketハイジャックを実行することも可能です**。これにより、ユーザーがGraphQLで予期しないアクションを実行することになります。
詳細については、以下を確認してください: 詳細については、以下を確認してください:
@ -461,13 +465,13 @@ GraphQLのCRSF脆弱性を悪用するのと同様に、**保護されていな
## GraphQLにおけるエイリアスを使用したレート制限のバイパス ## GraphQLにおけるエイリアスを使用したレート制限のバイパス
GraphQLでは、エイリアスはAPIリクエストを行う際に**プロパティの名前を明示的に指定する**ことを可能にする強力な機能です。この機能は、**同じタイプ**のオブジェクトの**複数のインスタンス**を単一のリクエスト内で取得するのに特に便利です。エイリアスを使用することで、GraphQLオブジェクトが同じ名前の複数のプロパティを持つことを妨げる制限を克服できます。 GraphQLでは、エイリアスはAPIリクエストを行う際に**プロパティの名前を明示的に指定する**ことを可能にする強力な機能です。この機能は、**同じタイプ**のオブジェクトの**複数のインスタンスを単一のリクエスト内で取得する**のに特に便利です。エイリアスを使用することで、GraphQLオブジェクトが同じ名前の複数のプロパティを持つことを妨げる制限を克服できます。
GraphQLエイリアスの詳細な理解のためには、次のリソースを推奨します: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases)。 GraphQLエイリアスの詳細な理解のために、以下のリソースを推奨します: [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases)。
エイリアスの主な目的は、数多くのAPI呼び出しの必要性を減らすことですが、エイリアスを利用してGraphQLエンドポイントに対してブルートフォース攻撃を実行するという意図しない使用例が特定されています。これは、一部のエンドポイントがブルートフォース攻撃を防ぐために**HTTPリクエストの数**を制限するレートリミッターによって保護されているため可能です。しかし、これらのレートリミッターは、各リクエスト内の操作の数を考慮しない場合があります。エイリアスを使用する、単一のHTTPリクエスト内に複数のクエリを含めることができるため、そのようなレート制限を回避できます。 エイリアスの主な目的は、数多くのAPI呼び出しの必要性を減らすことですが、エイリアスを利用してGraphQLエンドポイントに対してブルートフォース攻撃を実行するという意図しない使用例が特定されています。これは、一部のエンドポイントがブルートフォース攻撃を防ぐために**HTTPリクエストの数**を制限するレートリミッターによって保護されているため可能です。しかし、これらのレートリミッターは、各リクエスト内の操作の数を考慮しない場合があります。エイリアスを使用すると、単一のHTTPリクエスト内に複数のクエリを含めることができるため、そのようなレート制限を回避できます。
以下の例を考えてみてください。これは、エイリアス付きクエリを使用してストアの割引コードの有効性を確認する方法を示しています。この方法は、複数のクエリを1つのHTTPリクエストにまとめるため、レート制限を回避できる可能性があり、同時に多数の割引コードの確認を可能にします。 以下の例を考えてみてください。これは、エイリアス付きクエリを使用してストアの割引コードの有効性を確認する方法を示しています。この方法は、複数のクエリを1つのHTTPリクエストにまとめるため、レート制限を回避できる可能性があり、同時に多数の割引コードの確認を可能にします。
```bash ```bash
# Example of a request utilizing aliased queries to check for valid discount codes # Example of a request utilizing aliased queries to check for valid discount codes
query isValidDiscount($code: Int) { query isValidDiscount($code: Int) {
@ -486,7 +490,7 @@ valid
### Alias Overloading ### Alias Overloading
**Alias Overloading**は、攻撃者が同じフィールドに対して多くのエイリアスでクエリを過負荷にするGraphQLの脆弱性であり、バックエンドリゾルバがそのフィールドを繰り返し実行する原因となります。これによりサーバーリソースが圧倒され、**Denial of Service (DoS)**につながる可能性があります。例えば、以下のクエリでは、同じフィールド(`expensiveField`がエイリアスを使用して1,000回要求され、バックエンドがそれを1,000回計算することを強制され、CPUやメモリが枯渇する可能性があります **Alias Overloading**は、攻撃者が同じフィールドに対して多くのエイリアスでクエリを過負荷にするGraphQLの脆弱性であり、バックエンドリゾルバがそのフィールドを繰り返し実行する原因となります。これによりサーバーリソースが圧倒され、**サービス拒否DoS**につながる可能性があります。例えば、以下のクエリでは、同じフィールド(`expensiveField`がエイリアスを使用して1,000回要求されており、バックエンドはそれを1,000回計算することを強いられ、CPUやメモリが枯渇する可能性があります
```graphql ```graphql
# Test provided by https://github.com/dolevf/graphql-cop # Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "Content-Type: application/json" \ curl -X POST -H "Content-Type: application/json" \
@ -497,7 +501,7 @@ curl -X POST -H "Content-Type: application/json" \
### **配列ベースのクエリバッチ処理** ### **配列ベースのクエリバッチ処理**
**配列ベースのクエリバッチ処理**は、GraphQL APIが単一のリクエストで複数のクエリをバッチ処理することを許可する脆弱性であり、攻撃者が同時に大量のクエリを送信できるようになります。これにより、すべてのバッチ処理されたクエリが並行して実行され、バックエンドが圧倒され、過剰なリソースCPU、メモリ、データベース接続を消費し、最終的には**サービス拒否DoS**につながる可能性があります。バッチ内のクエリ数に制限がない場合、攻撃者はこれを用してサービスの可用性を低下させることができます。 **配列ベースのクエリバッチ処理**は、GraphQL APIが単一のリクエストで複数のクエリをバッチ処理することを許可する脆弱性であり、攻撃者が大量のクエリを同時に送信できるようにします。これにより、すべてのバッチ処理されたクエリが並行して実行され、バックエンドが圧倒され、過剰なリソースCPU、メモリ、データベース接続を消費し、最終的には**サービス拒否DoS**につながる可能性があります。バッチ内のクエリ数に制限がない場合、攻撃者はこれを用してサービスの可用性を低下させることができます。
```graphql ```graphql
# Test provided by https://github.com/dolevf/graphql-cop # Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" \ curl -X POST -H "User-Agent: graphql-cop/1.13" \
@ -505,7 +509,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" \
-d '[{"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}]' \ -d '[{"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}]' \
'https://example.com/graphql' 'https://example.com/graphql'
``` ```
この例では、10の異なるクエリが1つのリクエストにバッチ処理され、サーバーがそれらを同時に実行することを強制します。より大きなバッチサイズや計算コストの高いクエリで悪用されると、サーバーが過負荷になる可能性があります。 この例では、10の異なるクエリが1つのリクエストにバッチ処理され、サーバーにすべてを同時に実行させることを強制します。より大きなバッチサイズや計算コストの高いクエリで悪用されると、サーバーが過負荷になります。
### **ディレクティブオーバーローディング脆弱性** ### **ディレクティブオーバーローディング脆弱性**
@ -517,7 +521,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" \
-d '{"query": "query cop { __typename @aa@aa@aa@aa@aa@aa@aa@aa@aa@aa }", "operationName": "cop"}' \ -d '{"query": "query cop { __typename @aa@aa@aa@aa@aa@aa@aa@aa@aa@aa }", "operationName": "cop"}' \
'https://example.com/graphql' 'https://example.com/graphql'
``` ```
前の例では、`@aa`は**宣言されていない可能性がある**カスタムディレクティブであることに注意してください。通常存在する一般的なディレクティブは**`@include`**です: 前の例では、`@aa`は**宣言されていない可能性がある**カスタムディレクティブで。通常存在する一般的なディレクティブは**`@include`**です:
```bash ```bash
curl -X POST \ curl -X POST \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
@ -535,7 +539,7 @@ curl -X POST \
### **フィールド重複脆弱性** ### **フィールド重複脆弱性**
**フィールド重複**は、GraphQLサーバーが同じフィールドを過剰に繰り返すクエリを許可する脆弱性です。これにより、サーバーは各インスタンスのためにフィールドを冗長に解決する必要があり、重要なリソースCPU、メモリ、データベース呼び出しを消費します。攻撃者は、数百または数千の繰り返されたフィールドを持つクエリを作成することができ、高負荷を引き起こし、最終的には**サービス拒否DoS**につながる可能性があります。 **フィールド重複**は、GraphQLサーバーが同じフィールドを過剰に繰り返すクエリを許可する脆弱性です。これにより、サーバーは各インスタンスのためにフィールドを冗長に解決する必要があり、重要なリソースCPU、メモリ、データベース呼び出しを消費します。攻撃者は何百または何千もの繰り返されたフィールドを持つクエリを作成でき、高負荷を引き起こし、最終的には**サービス拒否DoS**につながる可能性があります。
```bash ```bash
# Test provided by https://github.com/dolevf/graphql-cop # Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \