2

I'm using gqlgen package to create GraphQL server. However, I can't limit the amount of the alias. FixedComplexityLimit limits the complexity of the query. It is possible in JS community thanks to graphql-no-alias npm package. I need that kind of thing.

I want to limit the amount of the alias to prevent the batching attack. Let's try to explain by giving an example.

query {
  productsByIds(productIds: "353573855") {
    active {
      id
      path
      title
  }
  productsByIds2: productsByIds(productIds: "353573855") {
    active {
      id
      path
      title
    }
  }
}

The above query should give an error. However, the below should work. This is just an example I have more complex schemas that's why the complexity limit didn't work for me.

query {
 productsByIds(productIds: "353573855") {
   active {
     id
     path
     title
 }
 products {
   active {
     id
     path
     title
   }
 }
}
  • Well, maybe you can just evaluate the request by yourself? `oCtx := graphql.GetOperationContext(ctx); selectionSet := oCtx.Operation.SelectionSet` - and then analyse this `SelectionSet`. – NotX Jan 05 '23 at 20:12
  • I tried but I think it's not a good solution. I might provide an error message for unexpected requests but it still gets the same amount of requests even. – Furkan Topaloğlu Jan 05 '23 at 20:49
  • I think just _getting_ the amount of requests isn't a problem. You can limit the allowed request size in you router's config. `graphql-no-alias` is also just some middle where which won't prevent the incoming request but just its processing, rather similar to what you can do in gqlgen's `resolver`. – NotX Jan 06 '23 at 09:00

1 Answers1

0

I'm afraid you have to come with something on your own for that. If you think the request itself or the response could become too large, you can limit it in your router config. For example, with fiber you could do:

routerConfig := fiber.Config{ReadBufferSize: maxRequestSize, WriteBufferSize: maxResponseSize};
router := fiber.New(routerConfig)
router.Post("/graphql", adaptor.HTTPHandler(gqlHandler))

If it's just really the aliases you want to prevent, you need to parse the request. You can either do so by some custom middle ware before the request gets passed to the gqlHandler (advantage: you can stop parsing the request in total in case of an alias request, disadvantage: you're basically duplicating code from a library, and it needs to be parsed again later on if you don't drop the standard gqlHandler). Or, and that's what I propose, you check the parsed request.

import gqlLib "github.com/99designs/gqlgen/graphql"
...
oCtx := gqlLib.GetOperationContext(ctx)
fragmentToSelections := getFragmentsSelectionsByName(oCtx)
selectionSet := oCtx.Operation.SelectionSet

An alias can be detected by having an Alias that differs from the Name: enter image description here

file is just the query root in this example. selectionSet[0] is an unaliased request, selectionSet[1] is.

NotX
  • 1,516
  • 1
  • 14
  • 28
  • I copied the complexity package from gqlgen library as a new package I changed it to limit the amount of the alias. Thank you for your advice. It enlightened me. – Furkan Topaloğlu Jan 06 '23 at 13:02
  • @FurkanTopaloğlu Well, if you're taking that deep dive, maybe create a PR for gqlgen. I've seen you've already created an issue there. ;) It's definitely better if you can utilize the (maintained) official version of the code. – NotX Jan 06 '23 at 13:21