Skip to content

Security: kasir-barati/graphql-js-ts

Security

docs/security.md

Security in a GraphQL service

  • Auth: Authentication & authorization.
  • Operation safe-listing.
  • Execution timeouts.

Cross Site Request Forgery -- CSRF

  • Client must:
    • Send operations via GET.
    • Multipart upload requests must include Apollo-Require-Preflight.

Cross-Origin Resource Sharing -- CORS

  • 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

Denial of Service attack

  • 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.
  • 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.

There aren’t any published security advisories