GraphQLSwift / GraphQL

The Swift GraphQL implementation for macOS and Linux
MIT License
938 stars 72 forks source link

Disabling introspection e.g. in production #122

Closed alexsteinerde closed 1 year ago

alexsteinerde commented 1 year ago

Please correct me if I'm wrong. But as I understand correctly, introspection is currently always enabled and cannot be disabled. If that's true I would like to create a PR for this. But maybe I'm missing something.

NeedleInAJayStack commented 1 year ago

Yeah, the introspection query is always added to the schema via this line.

It's probably worth noting though that the reference JavaScript implementation appears to do the same thing, and doesn't appear to offer options to limit this. Introspection-disabling appears to typically be offered by packages on top that use validation rules: apollo example, other example.

I suppose that's all to say that I think it'd make sense to take a validation approach to this, and improve the validation system if that is not currently possible.

alexsteinerde commented 1 year ago

Actually there are multiple places where schema and type types are used. Here I prototyped the disabling of introspection natively: https://github.com/GraphQLSwift/GraphQL/compare/main...alexsteinerde:GraphQL:disable-introspection

I'm new to GraphQL validations. But with examples and by looking at a JavaScript implementation (https://github.com/helfer/graphql-disable-introspection/blob/master/index.js) I would say the following validation function would work, right?

func disableIntrospectionValidation(context: ValidationContext) -> Visitor {
    return Visitor(enter: { node, _, _, _, _ in
        if let field = node as? Field, ["__schema", "__type"].contains(field.name.value) {
            context.report(error: .init(message: "GraphQL introspection is not allowed, but the query contained __schema or __type", nodes: [node]))
        }
        return .continue
    })
}
alexsteinerde commented 1 year ago

If that validation works, the change would need to be in Graphiti to pass optional validation functions into the execution.

NeedleInAJayStack commented 1 year ago

Yeah, that validation looks correct. I also think that adding validation support to Graphiti sounds like a great, general improvement that would serve many use cases. Thanks, and awesome work!

alexsteinerde commented 1 year ago

I'll submit a proposal for a PR once I find the time.

alexsteinerde commented 1 year ago

I created a PR in Graphiti and will close this issue. https://github.com/GraphQLSwift/Graphiti/pull/105