GraphQl No Batched Queries Validation
Graphql validation to disable batched queries and mutations that can be sent to the GraphQL server. By default, only one query or mutation per request is allowed.
// batch query attack (hello DoS)
query {
getUsers(first: 1000)
second: getUsers(first: 2000)
third: getUsers(first: 3000)
fourth: getUsers(first: 4000)
}
// or batch login attack
mutation {
login(pass: 1111, username: "ivan")
second: login(pass: 2222, username: "ivan")
third: login(pass: 3333, username: "ivan")
fourth: login(pass: 4444, username: "ivan")
}
`
You can read more batching attacks here: https://lab.wallarm.com/graphql-batching-attack/
Instalation
npm i graphql-no-batched-queries
Usage
In the next example, we are going to use express-graphql
as our graphql server.
The validation function accepts one parameter allow
which declares the default number of allowed queries or mutations per request.
const express = require('express')
const { graphqlHTTP } = require('express-graphql')
const createValidation = require('graphql-no-batched-queries')
// allow two queries or mutations per request (default is one)
const validation = createValidation({ allow: 2 })
const app = express()
app.use(
'/graphql',
graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
validationRules: [validation] //add the validation function
})
)
app.listen(4000)
Customizing the error message
The error
message that is reported when the validation fails can also be customized. You can return a GrahphQLError
instance or just a string
that will be used as the error message.
const validation = createValidation({errorFn:(
maxAllowed: number,
ctx: ValidationContext
): GraphQLError {
return new GraphQLError(
`Hey! allowed number of calls for ${typeName}->${fieldName} has been exceeded (max: ${maxAllowed})`
)
//or
return 'just the message'
}
})
Envelop Plugin
If you are using GraphQL Envelop. I have made a plugin that uses this validation.
GraphQl No Alias Directive
I've also made a directive that disables alias
functionality of the query, meaning that you can't send the same queries or mutations to the server. It pairs nicely with this one, in case you want to allow more than one query or mutation, but they can't be the same.
License
This project is licensed under the MIT License - see LICENSE file for details