- Auth: Authentication & authorization.
- Operation safe-listing.
- Or alternatively:
- Depth-limiting.
- Breadth-limiting.
- Alias limits.
- Cycle rejection.
- Cost analysis.
- Or alternatively:
- Execution timeouts.
- Client must:
- Send operations via
GET
. - Multipart upload requests must include
Apollo-Require-Preflight
.
- Send operations via
- An extra layer of protection.
- An HTTP-header-based protocol that enables a server to dictate:
- Which origins can access its resources.
- Which types of HTTP requests are allowed.
- # Same-origin policy (SOP):
- A security mechanism.
- Restricts scripts on one origin from interacting with resources from another origin.
- If two URLs differ in their domain, protocol, or port, then those URLs come from two different origins.
Tip
- CORS is a new protocol to relax SOP and safely share resources across different origins.
- Related to browser security: cannot prevent other softwares from making requests for resources on the server. Like
cURL
that can by pass the CORS configurations. - Learn how to implement it in AWS, ExpressJS, and with GitHub self-hosted runners here.
-
Protect your GraphQL servers against resource exhaustion and DoS attacks.
- Reject queries to your GraphQL server that are deemed too costly to execute.
- Learn more here.
-
To do this we need to perform analysis the cost of executing a query.
-
There are tools that can help us to do this:
-
It is directly related to your GraphQL schema design:
-
If you can send the following query to your GraphQL service:
query { getPosts { id author { posts { id author { posts { id author { posts { id author { id } } } } } } } } }
-
And let's assume like in our example you're using a tool like join-monster which will convert your query into this SQL:
SELECT "getPosts"."id" AS "id", "author"."id" AS "author__id", "posts"."id" AS "author__posts__id", "author$"."id" AS "author__posts__author$__id", "posts$"."id" AS "author__posts__author$__posts$__id", "author$$"."id" AS "author__posts__author$__posts$__author$$__id", "posts$$"."id" AS "author__posts__author$__posts$__author$$__posts$$__id", "author$$$"."id" AS "author__posts__author$__posts$__author$$__posts$$__author$$$__id" FROM post "getPosts" LEFT JOIN public.user "author" ON "author".id = "getPosts"."authorId" LEFT JOIN post "posts" ON "author".id = "posts"."authorId" LEFT JOIN public.user "author$" ON "author$".id = "posts"."authorId" LEFT JOIN post "posts$" ON "author$".id = "posts$"."authorId" LEFT JOIN public.user "author$$" ON "author$$".id = "posts$"."authorId" LEFT JOIN post "posts$$" ON "author$$".id = "posts$$"."authorId" LEFT JOIN public.user "author$$$" ON "author$$$".id = "posts$$"."authorId"
-
Note
A couple of notes:
- The project for this can be found here:
apps/dos-attack-example
.- To learn how to run it read this doc.
- And this query on my local system took a long time so I just killed my project and never bother to see if this actually can return any result.