Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lock introspection to a specific query #4871

Open
smyrick opened this issue Mar 27, 2024 · 0 comments
Open

Lock introspection to a specific query #4871

smyrick opened this issue Mar 27, 2024 · 0 comments

Comments

@smyrick
Copy link
Member

smyrick commented Mar 27, 2024

Is your feature request related to a problem? Please describe.

I want to allow introspection on my supergraph but I do not want to keep it open for attackers to abuse and run custom or abusive introspection operations. This can lead to cache blowout or coprocessor overload. Instead we should restrict introspection to return a fixed response.

Describe the solution you'd like

There are a few possible outcomes, but as a valid client doing introspection the result I need is the JSON response of an introspection result

  • We could restrict the GraphQL operation to a fixed operation, that must match by hash (See below).
  • We could provide a new, fixed endpoint to get the JSON response /introspection
  • We could provide a new, fixed endpoint to get the SDL text response /sdl (this would require clients to process but still provides the schema)
  • We could analyze the request for the number of recursive nodes and have logic to determine if it not a good faith introspection query, like graphql-java did.
  • We could provide a way for users to decide per-request if introspection should be allowed

Hard coded operation

Hard code the introspection query as a saved operation in Router, ideally matching the one returned from graphql-js, and only allow that as a valid introspection option. This can be used then to return the result or from a fixed endpoint

Router config

supergraph:
  introspection:
    enabled: true
    restricted: true
graphql-js introspection details
import { getIntrospectionQuery } from 'graphql'
console.log(getIntrospectionQuery())

SHA-256 Hash of below string

1ffdf7edbe908ace0912a127bd35dce7b6ee2d06d3ed41f70463d6f7a95f4fab

Full Operation String

query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description

      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description

  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
                ofType {
                  kind
                  name
                  ofType {
                    kind
                    name
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Describe alternatives you've considered

As a GraphOS customer, I could use Persisted Queries and lock down this operation myself in the safelist

I could also disable introspection and ask my client teams to pull the schema with Rover from GraphOS so my API is not being abused and defer the request volume to Apollo's APIs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant