webonyx / graphql-php

PHP implementation of the GraphQL specification based on the reference implementation in JavaScript
https://webonyx.github.io/graphql-php
MIT License
4.64k stars 561 forks source link

Disable field suggestions when introspection disabled #454

Open erikgaal opened 5 years ago

erikgaal commented 5 years ago

Hi! While assessing the security of our GraphQL app, I noticed something strange. Our api is private, which means that we have our introspection disabled. However, when trying to guess the queries and mutations available, you receive suggestions of valid queries. I am aware that anyone should never rely on the hiding of information to provide security, but this makes it much easier for a malicious user to uncover the schema. You can find an example below.

My workaround for now is to provide an alternative message in the ErrorHandler using $e->getCategory() === Error::CATEGORY_GRAPHQL. It would be great for a way to disable these suggestions with a config, or better, to disable these when introspection is disabled.

▲ (local) ~ curl "http://localhost/graphql?query=mutation\{create\}" -L
{"errors":[{"message":"Cannot query field \"createSesion\" on type \"RootMutation\". Did you mean \"createSession\", \"createUser\", \"createFile\", or \"createImage\"?","category":"graphql"}]}
vladar commented 5 years ago

Makes sense for me. PR is welcome!

davidwhthomas commented 5 years ago

Not too sure on the suggested patch for this one, would need some way to check the currently applied validation rules.

I used a workaround by removing the validation plugins such as FieldsOnCorrectType and overriding with a custom one that doesn't include suggestions.

gmgale commented 1 year ago

Did this ever get solved? I have the same issue now and a bit stuck! Perhaps @erikgaal could you elaborate on your workaround a bit please? Any help is appreciated!

shmax commented 1 year ago

Just curious--if you're really worried about folks snooping your schema, why not just close all arbitrary-query access to the endpoint entirely and use persisted queries?