GraphQL API Support - Introduction

As of HawkScan v.0.6.6, StackHawk now provides GraphQL API scanning support.

Enabling this feature allows HawkScan to perform introspection on your GraphQL and begin building queries that are targeted towards the environment. HawkScan does this by enumerating all available fields, input types, input parameters and output types for each discovered Query and Mutation operation.

The current scan behavior generates payloads for fields using individual input parameters and output types as well as full query payloads which contain all possible input parameters and output types associated with a field. This behavior will be configurable in upcoming releases of HawkScan.

Here’s how it works:

  1. HawkScan initially queries the GraphQL schema endpoint URI for full introspection and performs discovery on all discovered fields along with their associated types and parameters.
  2. Once fields have been discovered HawkScan then proceeds to generate POST requests based on these findings and provides test values to be inserted in each of the available parameters. This generation occurs for both Query and Mutation operations.
    • GET requests are available where applicable and can be configured as the primary request type in upcoming releases of HawkScan.
  3. Once the GraphQL payloads have been generated HawkScan collects actionable responses and sends them to the StackHawk Findings page for review and remediation. Once there, requests will be displayed with their associated request URI as well as the original payload used in the audit.

As stated previously, the results gathered from the scan will be presented with the GET form of the request URI as well as the POST body used in the request.

The following sections should help to get you started with GraphQL vulnerability assessment in HawkScan:

Please note: Enabling GraphQL support may increase scan times based on the size of the current schema. Be sure to also take note of other scanning methods that may be configured in the engine such as OpenAPI support. This may also result in longer than usual scan times.

Also please note: Recursion of the graph searches to a max depth of three before backing off in order to avoid following any circular references.

GraphQL Configuration

GraphQL support in StackHawk requires only that graphQL be set to true in the application’s stackhawk.yaml. This provides coverage for comprehensive GraphQL POST auditing, however additional parameters may be set to help tune scanning:

app:
  graphQL: true
  graphqlConf:
    schemaPath: '/graphql'
    requestMethod: 'POST'
    batchQueries: 'True'
    maxDepth: 3
    uriMaxLength: 4000

Please refer to the stackhawk.yml Reference for information on these parameters.

Provide the GraphQL Introspection Endpoint for the GraphQL Schema and HawkScan does the rest. This URI is typically a path that ends with /graphql, but could be any predetermined name. This configuration also works side-by-side with new or existing OpenAPI configurations that may be present in an application configuration.

It is worth noting that the more StackHawk’s HawkScan is executed against an application, the more interesting the payloads become that are generated for the application.

More information on GraphQL fields, types, variables and operations can be found in the following series of documents:

Example GraphQL Schema Introspection

GraphQL specifies the requirement for allowing introspection requests to the GraphQL API. An example of a response to such an introspection request may appear similar to the following:

{
  "data": {
    "__schema": {
      "queryType": {
        "name": "Query"
      },
      "mutationType": {
        "name": "Mutation"
      },
      "subscriptionType": null,
      "types": [
        {
          "kind": "OBJECT",
          "name": "Query",
          "description": null,
          "fields": [
            {
              "name": "post",
              "description": null,
              "args": [
                {
                  "name": "where",
                  "description": null,
                  "type": {
                    "kind": "NON_NULL",
                    "name": null,
                    "ofType": {
                      "kind": "INPUT_OBJECT",
                      "name": "PostWhereUniqueInput",
                      "ofType": null
                    }
                  },
                  "defaultValue": null
                }
              ],
              "type": {
                "kind": "OBJECT",
                "name": "Post",
                "ofType": null
              },
              "isDeprecated": false,
              "deprecationReason": null
            }
		  ]
	    }
	  ]
	}
  }
}

Example of a generated GraphQL request

An example of a POST to the GraphQL API may appear as follows (formatted for readability):

POST http://localhost:4000 HTTP/1.1
User-Agent: HawkScan/2.0; StackHawk, Inc. (https://www.stackhawk.com)
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 296
Accept: application/json
Content-Type: application/json
Host: localhost:4000

{
  "query": "query filterPosts($searchString:String ) { filterPosts(searchString:$searchString) { id } }",
  "variables": {
    "searchString": "KaaaKaww!"
  }
}

In addition to POST requests, HawkScan also provides support for making GET requests on GraphQL Query operations.

Using the prior POST example from above, such URIs may appear as follows:

http://localhost:4000?query=filterPosts($searchString:String%20)%20%7B%20filterPosts(searchString:$searchString)%20%7B%20id%20%7D%20%7D&variable