getUsers(name: "John") {
name
getGroups {} # The groups John has
}
getGroups(name: "Developers") {
getUsers {
name # All the names of the developers
}
}
It's very easy to make a Denial of Service query like this
getUsers{ # All the users
getGroups{ # All the groups of all the users
getUsers{ # x ^ 2
getGroups{ # x ^ "infinity"
}
}
}
}
If we make a passalong object in source which keeps counters for each query, we could limit how many time a query is allowed to exist inside a nested graph.
getUsers.resolver({
context,
source
}) {
if(source.queryCounts.getUsers >= context.queryLimits.getUsers) {
throw new Error(`You are not allowed to call getUser more than ${context.queryLimits.getUsers} times in a graph`);
}
source.queryCounts.getUsers++;
return {
...results
queryCounts: source.queryCounts
};
}
A query such as this, would still work, as source is only passed down a nested graph.
getUsers(name: "John") {
name
}
alias: getUsers(name: "Jane") {
name
}
This is related to https://github.com/enonic/lib-graphql/issues/133
But goes beyond it.
Lets say we have two queries
And both these graphs are valid and useful:
It's very easy to make a Denial of Service query like this
If we make a passalong object in source which keeps counters for each query, we could limit how many time a query is allowed to exist inside a nested graph.
A query such as this, would still work, as source is only passed down a nested graph.