Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code snippets for "Securing Your GraphQL API from Malicious Queries" blog post
app.use('/api', graphqlServer({
validationRules: [depthLimit(10)]
}))
query evilQuery {
thread(id: "54887141-57a9-4386-807c-ed950c4d5132") {
messageConnection(first: 100) { ... }
participants(first: 100) {
threadConnection(first: 100) { ... }
communityConnection { ... }
channelConnection { ... }
everything(first: 100) { ... }
}
}
}
query maliciousQuery {
thread(id: "some-id") {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
messages(first: 99999) {
thread {
# ...repeat times 10000...
}
}
}
}
}
}
}
}
{
"scripts": {
"postbuild": "persistgraphql src api/query-whitelist.json"
}
}
const PaginationAmount = GraphQLInputInt({
name: 'PaginationAmount',
min: 1,
max: 100,
});
type Participant {
# The complexity of getting one thread in a thread connection is 3, and multiply that by the amount of threads fetched
threadConnection(first: PaginationAmount, after: String): ThreadConnection @cost(complexity: 3, multiplier: "first")
}
type Thread {
participants(first: PaginationAmount,...): [Participant] @cost(complexity: 2, multiplier: "first")
}
app.use('/api', graphqlServer((req, res) => {
const query = req.query.query || req.body.query;
// TODO: Get whitelist somehow
if (!whitelist[query]) {
throw new Error('Query is not in whitelist.');
}
/* ... */
}))
app.use('*', (req, res, next) => {
const query = req.query.query || req.body.query || '';
if (query.length > 2000) {
throw new Error('Query too large');
}
next();
})
type Thread {
messages(first: PaginationAmount, after: String): [Message]
}
type Thread {
messages(first: Int, after: String): [Message]
}
type Message {
thread: Thread
}
type Query {
thread(id: ID!): Thread
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.