ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.03k stars 724 forks source link

Implement restricted access to GraphiQL/Playground/Voyager UIs. #1177

Closed tohagan closed 3 years ago

tohagan commented 4 years ago

Is your feature request related to a problem? Please describe. Apply an Authorization role or policy to restrict access to GraphiQL, Playground, Voyager

Describe the solution you'd like

Probably you'd just add an option to specify an authorization policy name in GraphiQLOptions, PlaygroundOptions and VoyagerOptions.

Describe alternatives you've considered

Currently we just disable GraphiQL/Playground/Voyager for Release build.

Additional context

The more general problem is to apply an Authorization policy to ...

cescoferraro commented 4 years ago

@michaelstaib we are going to production with hotchocolate in the upcoming weeks. thankssss!

We would love the Schema Authorization feature. In our use case we want to be able to secure the introspection query all together. i think its what @tohagan was refering as Schema Queries v1 global we are already authorizing all queries and mutations with :hot_pepper: :chocolate_bar:

michaelstaib commented 4 years ago

@cescoferraro we have that on our list for V11. So, it will come. We might even push this out with 10.3.0.

tohagan commented 4 years ago

Actually the bigger issue here is restricting access (or disabling!) introspection queries.

michaelstaib commented 4 years ago

@tohagan that is possible, you can extend the introspection types and restrict them.

michaelstaib commented 4 years ago

You just have to add our authorize directives.

michaelstaib commented 4 years ago

So, just regarding security, you can already do a lot with hc to make your endpoint super secure. That is why I do not consider this pressing.

Securing Playground is just securing the route.

But you can already whitelists queries, use persisted queries, put authorization directives on any of your fields / including introspection. You can even put custom middleware on your introspection fields to secure them.

Moreover, you can control the execution depth and the allowed cost of a query. You can even intercept the input coercion if you so desire to handle the coercion of inputs yourself.

So, from a security point this is not really a big issue.

michaelstaib commented 4 years ago

Also, you can add custom query validation rules which could further harden your endpoint.

michaelstaib commented 4 years ago

Regarding the endpoint security: https://github.com/ChilliCream/hotchocolate/pull/1190

tohagan commented 4 years ago

Thanks ... that all sounds great... so then the missing bit is documenting the risk and how to do these things. I read some security articles on GraphQL and a common issue raised was securing introspection. Now that I know the issue I’ll act on it but the next person learning HC likely won’t know these security risks, nor what to do to fix them.

michaelstaib commented 4 years ago

@tohagan do you want to do a pr for that? I can assist you with putting all the information together. You could add a section to the security section of the documentation, maybe even with a reference to the article that you have read.

We are using docusaurus and the docs are located here: https://github.com/ChilliCream/hotchocolate-docs

Here is the security information that we already have: https://hotchocolate.io/docs/security

tohagan commented 4 years ago

I've not forgotten your PR request. Just been buried other non GraphQL stuff + xmas holidays. I think I'd need to refer to an example of how to code restricting access to introspection queries but not sure how to go about this despite your guidance above.

vhatsura commented 4 years ago

@tohagan that is possible, you can extend the introspection types and restrict them.

@michaelstaib, is it possible to somehow add authorize directive for the built-in introspection __schema query?

michaelstaib commented 4 years ago

@vhatsura yes it is. you can add a authorize directive on the query type and associate it with a authorization policy.

In the policy you have access to the resolver context and you can check if the current field is a introspection field.

The auth policy context as a property Resource which is the IResolverContext

On the IResolverContext => context.Field.IsIntrospection...

vhatsura commented 4 years ago

you can add a authorize directive on the query type and associate it with a authorization policy.

@michaelstaib, sorry for that but I cannot familiar enough with HC, can you post a small example snippet for that? For our query type we have the following:

protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
{
    //descriptor.Authorize(Scopes.Full); // authorize directive for all queries
    descriptor.Field(t => t.GetFetchRocket(default, default)).Authorize(Scopes.Full); // authorize directive for fetchRocket query
}

Is it possible to have similar for __schema introspection query without adding additional middleware?

brent-williams commented 3 years ago

From @tohagan:

I read some security articles on GraphQL and a common issue raised was securing introspection.

From @vhatsura:

sorry for that but I cannot familiar enough with HC, can you post a small example snippet for that?

Same issue, require some way to completely disable introspection on some deployments for security reasons but unsure how to do so. @michaelstaib your sketch of solution sounds like would solve the issues if you can provide a bit more detail on where/how to hook up an IsIntrospection filter.

michaelstaib commented 3 years ago

Playground has now been replaces with bcp and uses the new endpoint API, this allows for using authorization rules.

Zero3 commented 3 years ago

@michaelstaib echoing what was requested a couple of times above: Could you provide a simple example of how to disable introspection queries? Thanks! :)

huysentruitw commented 3 years ago

I have figured something out for v11:

internal class NoIntrospectionDocumentValidatorVisitor : TypeDocumentValidatorVisitor
{
    protected override ISyntaxVisitorAction Enter(FieldNode node, IDocumentValidatorContext context)
    {
        if (node.Name.Value == IntrospectionFields.Schema || node.Name.Value == IntrospectionFields.Type)
        {
            IError error = ErrorBuilder.New().SetMessage("Introspection queries are disabled").Build();
            context.Errors.Add(error);
            return new BreakSyntaxVisitorAction();
        }

        return base.Enter(node, context);
    }
}

Register in Startup.cs as:

services
    .AddValidation()
    .TryAddValidationRule<NoIntrospectionDocumentValidatorVisitor>();
gallargit commented 3 years ago

I have figured something out for v11: ...

Hi, your proposed solution does not work, it fails here

services
    .AddValidation()
    .TryAddValidationRule<NoIntrospectionDocumentValidatorVisitor>();

The error given is this one

The type 'NoIntrospectionDocumentValidatorVisitor' cannot be used as type parameter 'T' in the generic type or method 'HotChocolateValidationBuilderExtensions.TryAddValidationRule<T>(IValidationBuilder)'. There is no implicit reference conversion from 'NoIntrospectionDocumentValidatorVisitor' to 'HotChocolate.Validation.IDocumentValidatorRule'.

Edit: I'm using the latest Hot chocolate v11 version

PascalSenn commented 3 years ago

@huysentruitw @gallargit

In the lastest preview you can just do

services
                 .AddGraphQLServer() 
                 .AddIntrospectionAllowedRule() /// <-----
                 ...