---
title: "GraphQL Configuration"
description: "GraphQL discovery, enumeration and scanning support using HawkScan 2.0+"
url: https://docs.stackhawk.com/hawkscan/configuration/graphql-configuration/
---

# GraphQL Configuration

HawkScan supports security testing for GraphQL APIs.

HawkScan will perform introspection of a GraphQL app to generate routes based on available operations. The scanner can be configured to enumerate all available types and input parameters for `Query` and `Mutation` together, or for each individual type separately.

See [GraphQL configuration](https://docs.stackhawk.com/hawkscan/configuration/#appgraphqlconf) settings for more details.

## How It Works

To perform application security testing against a GraphQL API, HawkScan runs the following processes:

1. The scanner initially introspects the GraphQL schema endpoint for available types and operations.
2. After collecting input types and arguments, HawkScan generates requests and populates arguments with test values to begin spidering the GraphQL API in preparation for attack.
3. Requests sent as `POST` by default, while using `GET` requests is a configurable option. See [requestMethod](https://docs.stackhawk.com/hawkscan/configuration/#appgraphqlconf) in the GraphQL configurations for more info
4. The active scanner goes to work on each route discovered by the spider.

> **Note:** If your `stackhawk.yml` file has other features enabled such as [OpenAPI configuration](https://docs.stackhawk.com/hawkscan/configuration/openapi-configuration/) or the [AJAX Spider](https://docs.stackhawk.com/hawkscan/configuration/#hawkspider), you may experience longer scan completion times in larger environments.

<a id="graphql-configuration"></a>

## GraphQL Configuration

To scan a GraphQL application:

1. set `app.graphqlConf.enabled` to `true` in `stackhawk.yml`
2. configure a GraphQL schema (introspection endpoint or schema file)

Configuration examples:

Example 1 — Point HawkScan to your application’s GraphQL introspection endpoint:

```yaml title="stackhawk.yml"
app:
  host: http://localhost:3000
  graphqlConf:
    enabled: true
    schemaPath: /graphql # relative path to the introspection endpoint
    operation: MUTATION
    requestMethod: GET
```

Example 2 — Import a JSON-formatted schema file into HawkScan:

```yaml title="stackhawk.yml"
app:
  host: http://localhost:3000
  graphqlConf:
    enabled: true
    filePath: relative/path/to/gql/schema.json # path to schema file
    operation: MUTATION
    requestMethod: GET
```

Note: HawkScan requires that either schemaPath OR filePath be configured. It is unusual to configure both, but sometimes necessary. If both filePath and schemaPath are set, the schema will be loaded from the file system and the schemaPath will be used for requests to the API.

### `app.graphqlConf.schemaPath`

Provides a relative path to the [introspection](https://graphql.org/learn/introspection/) endpoint.

This should also be the GraphQL API endpoint for sending queries.

Notes:

- if no schema path has been provided, the scanner will look for it at `/graphql` by default
- a `schemaPath` will need to be provided if the GraphQL endpoint is not at `/graphql`

### `app.graphqlConf.filePath`

It is possible to provide the GraphQL schema as a JSON file. Provide the relative path to a JSON formatted GraphQL schema.

Notes:

- this path is relative to the HawkScan Docker context, which by default is the current working directory
- the schema file should start with `{"__schema":`, not `{"data":{"__schema":` (the latter is the output of an introspection query; HawkScan expects the schema itself)

### `app.graphqlConf.uriMaxLength`

Some queries can exceed recommended lengths when using the `GET` request method. Max URI length for `GET` requests will truncate long URIs and may result in misfired requests.

### `app.graphqlConf.operation`

By default, the spider generates operation requests for both `Query` and `Mutation` types. Use this option to target one or the other individually.

### `app.graphqlConf.excludeOperations`

To exclude particular GraphQL operations from being scanned, pass an array of objects with `name` and `type` as keys. The `name` is a string representing the name of the operation while the `type` is an enum representing the possible GraphQL operation types (`QUERY`, `MUTATION`, or `ALL` to exclude query and mutation operations with the same name) . `schemaPath` and `filePath` options are both compatible with this functionality.

```yaml title="stackhawk.yml"
app:
  host: http://localhost:3000
  graphqlConf:
    enabled: true
    schemaPath: /graphql
    excludeOperations:
      - name: filterPosts
        type: QUERY
      - name: updatePosts
        type: MUTATION
```

## Using Custom Variable Injection

The following is an example configuration using custom values:

```yaml
# in the "app" config...
app:
  graphqlConf:
    enabled: true
    schemaPath: /graphql
    requestMethod: POST
    operation: ALL
    # List of custom variables and a list of possible values to use for each of them.
    customVariables:
      - field: firstName
        values:
          - customFirstName1
          - customFirstName2
      - field: lastName
        values:
          - customLastName1
          - customLastName2
      - field: username
        values:
          - customUsername1
          - customUsername2
          - customUsername3
```

To achieve greater control over GraphQL custom variables, you have the option to include an operationName and an operationType (MUTATION or QUERY). These additional filters help in injecting custom variable values more selectively. When an operationName and/or operationType are specified, only requests that match that specific information will utilize the provided list of values for variable injection. This allows you to assign different sets of values for the same schema parameter name. For instance, if you have two separate operations that both use the `{userId}` parameter, you can use the operationName to assign distinct lists of potential values for each operation. Here’s an example of how to configure operation names and types:

```yaml
# in the "app" config
app:
  graphqlConf:
    enabled: true
    schemaPath: /graphql
    fakerEnabled: true
    customVariables:
      - field: title
        values:
          - customValue1
          - customValue2
        operationName: createPost
        operationType: MUTATION
      - field: content
        values:
          - $faker:paragraph
        operationType: QUERY
      - field: username
        values:
          - scannerLoginUsername
        operationName: login
      - field: username
        values:
          - scannerRegisterUsername
        operationName: register
      - field: password
        values:
          - scannerPassword
        operationName: login
        operationType: MUTATION
```

In the example above, the `title` will only be injected when the operationName is `createPost` and it is a `MUTATION` . The `content` param will be used wherever the parameter turns up in a `QUERY` operation, regardless of the operationName. for the `username` param, when the `login` operation is invoked, `scannerLoginUsername` will be used and when the `register` operation is invoked, `scannerRegisterUsername` will be used. Same idea with `password`, the value `scannerPassword` will only be injected on the `login` operation.

## Generating Smart Values for Parameters

You can configure which parameters will get generated smart values in the `stackhawk.yml` file in the graphqlConf section, by using the faker prefix (`$faker`) and a format as a custom value for a given parameter. For example:

```yaml
# in the "app" config...
app:
  graphqlConf:
    enabled: true
    schemaPath: /graphql
    requestMethod: POST
    operation: ALL
    # Enables used of the Faker library to generate smarter values
    fakerEnabled: true
    # List of custom variables and a list of possible values to use for each of them.
    customVariables:
      - field: customerEmail
        values:
          - $faker:email
      - field: customerPhone
        values:
          - $faker:phone
      - field: customerId
        values:
          - $faker:uuid
```

This configuration will randomly generate a properly formatted and random email address for `customerEmail`, phone number for `customerPhone`, and uuid for `customerId`.

### More Configuration Support

For more detailed configuration options, check out the [GraphQL Scanner Parameters](https://docs.stackhawk.com/hawkscan/configuration/#appgraphqlconf)

## Example GraphQL Schema Introspection

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

- [GraphQL Introspection](https://graphql.org/learn/introspection/)
- [GraphQL Fields](https://graphql.org/learn/queries/#fields)
- [GraphQL Variable Definitions](https://graphql.org/learn/queries/#variable-definitions)
- [GraphQL Operation Names](https://graphql.org/learn/queries/#operation-name)

HawkScan expects a well-formed GraphQL schema definition which conforms to the [GraphQL specification](https://graphql.org/learn/schema/).

A simple example:

```json
{
  "__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
          }
        ]
      }
    ]
  }
}
```

## HawkScan Generated Requests

HawkScan provides support for both `POST` and `GET` requests.

`POST` request example:

```http
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": "test search"
  }
}
```

`GET` request example:

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