Skip to content

Instantly share code, notes, and snippets.

@andyrichardson
Created November 12, 2020 12:48
Show Gist options
  • Save andyrichardson/0f9c7580c38d0fefa904046aa893131c to your computer and use it in GitHub Desktop.
Save andyrichardson/0f9c7580c38d0fefa904046aa893131c to your computer and use it in GitHub Desktop.
A secure method for checking if an incoming query is an introspection query.
const isIntrospectionQuery = (arg: string) => {
const query = parse(arg);
const opDefs = query.definitions.filter(d => d.kind == "OperationDefinition") as OperationDefinitionNode[];
// Must only have one definition
if (opDefs.length > 1) {
return false;
}
const selections = opDefs[0].selectionSet.selections;
// Must only have one selection
if (selections.length > 1) {
return false
}
const selection = selections[0];
// Must have single field
if (selection.kind !== "Field") {
return false;
}
if (selection.name.value !== "__schema") {
return false;
}
return true;
}
@andyrichardson
Copy link
Author

wouldn't this fail if the first selection isn't __schema or __type - but some other valid query selector?

@tbrannam yes that is correct (and intentional). The function returns true if (and only if) it is an introspection query.

Exclusively an introspection query

This gist: true
Your example: true

query IntrospectionQuery {
  __schema {
    queryType { name }
  }
}

A query with introspection fields

This gist: false
Your example: true

query IntrospectionQuery {
  user {
    id
  }
  __schema {
    queryType { name }
  }
}

If you check out this issue you'll see there are a number of folks taking your approach in order to determine whether auth is required. This is problematic as it means auth can be bypassed by accompanying a query with introspective fields, hence why I made this gist.

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