GraphQL Support
HawkScan is pioneering application 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 settings for more details.
How It Works
To perform application security testing against a GraphQL API, Hawkscan runs the following processes:
- The scanner initially introspects the GraphQL schema endpoint for available types and operations.
- 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.
- Requests sent as
POST
by default, while usingGET
requests is a configurable option. See requestMethod in the GraphQL configurations for more info - 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 or the AJAX Spider, you may experience longer scan completion times in larger environments.
GraphQL Configuration
To scan a GraphQL application:
- set
app.graphqlConf.enabled
totrue
instackhawk.yml
- configure a GraphQL schema (introspection endpoint or schema file)
Configuration examples:
Example 1 – Point HawkScan to your application’s GraphQL introspection endpoint:
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:
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 (do not configure both).
app.graphqlConf.schemaPath
Provides a relative path to the 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.
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
You can configure HawkScan to use custom values for any parameters that exist in your
GraphQL schema. Using custom values allows you to scan operations that
can potentially access real data and exercise more branches of your application’s
code than default static values that may not exist in the context of your application.
To provide custom values for your GraphQL schema’s params, include the
app.graphqlConf.customVariables
parameter in your stackhawk.yml
file.
The following is an example configuration using custom values:
# 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
If you provide a list of values for a custom variable, the scanner will select one
randomly for each operations that the custom variable belongs to. If you provide
a single value in the list for a variable, that value will be used. For any parameters
in the GraphQL schema that you do not provide custom values for in the
stackhawk.yml
file, HawkScan will fall back on default logic and use static values
based on their type.
Generating Smart Values for Parameters
By leveraging the Java Faker library,
HawkScan can generate smarter values when the proper information is supplied in the
GraphQL schema. To enable this feature, be sure the
graphqlConf.fakerEnabled
value is set to true
.
You can then 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:
# 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
Example GraphQL Schema Introspection
More information on GraphQL fields, types, variables and operations can be found in the following series of documents:
HawkScan expects a well-formed GraphQL schema definition which conforms to the GraphQL specification.
A simple example:
schema
{
"__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:
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!"
}
}
GET
request example:
http://localhost:4000?query=filterPosts($searchString:String%20)%20%7B%20filterPosts(searchString:$searchString)%20%7B%20id%20%7D%20%7D&variable