Code Monkey home page Code Monkey logo

Comments (17)

joemcbride avatar joemcbride commented on July 1, 2024 2

The client application calling the api controls the OperationName, so someone could easily bypass that check by giving their query a different name. The only way to truly disable being able to query introspection types would be to check for the __schema field. You could write a validation rule to do that.

from authorization.

joemcbride avatar joemcbride commented on July 1, 2024 2

Also, you would want to do this check before the query is executed vs. after. Validation rules run before the query is executed.

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024 1

@bioharz

Wherever you are running:
ExecutionResult result = await _executer.ExecuteAsync

Just add an condition afterwards like:

if (result.Operation.Name == "IntrospectionQuery" && !YourMethodThatReturnsIfDocsShouldShow)
{
     //Workaround
     result.Errors.Add(new ExecutionError(nameof(HttpStatusCode.Forbidden)));
}

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024 1

The client application calling the api controls the OperationName, so someone could easily bypass that check by giving their query a different name.

I'm a little confused by that - if his goal was the same mine, then the intention wasn't to block any other request type that isn't public, just the documentation look-ups. Otherwise in my model everything else is handled with MetaData and/or AuthorizationSettings.

To be clear with my question - what else could somebody send to the server to to-do an "IntrospectionQuery" besides "IntrospectionQuery"?

from authorization.

joemcbride avatar joemcbride commented on July 1, 2024 1

This is an introspection query with a different Operation name.

query aNameThatIChoose {
  __schema {
    types {
      name
    }
  }
}

from authorization.

sungam3r avatar sungam3r commented on July 1, 2024 1

Yes, there is a downside
query oops_not_a__schema { client { permissions__schema name } }

from authorization.

joemcbride avatar joemcbride commented on July 1, 2024 1

is doing a string check somehow less secure in this instance?

Probably not. Doing the check as a validation rule though you get the error in the GraphQL format and mitigate any potential bugs. All of the fields in the request are already being iterated over with other validation rules. Adding one more rule should not be a huge overhead and does not iterate over the whole query again, it just calls your validation rule while it iterates over them.

from authorization.

joemcbride avatar joemcbride commented on July 1, 2024 1

Schema Introspection Filtering is in the works: graphql-dotnet/graphql-dotnet#1179

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024

For now I'm doing like:

if (result.Operation.Name == "IntrospectionQuery" && !IsLocalhost())
		{

		}

from authorization.

bioharz avatar bioharz commented on July 1, 2024

Hi. Thank you for your contribution. May I ask you to provide us with example code. Thanks! PS: I'm stuck on the same issue.

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024

@joemcbride

public class SchemaValidationRule : IValidationRule
{
    public INodeVisitor Validate(ValidationContext context)
    {
        return new EnterLeaveListener(_ =>
        {
            _.Match<Field>(f =>
            {
                if (!ICanBeHere && f.Name == "__schema")
                {
                    var error = new ValidationError(
                        context.OriginalQuery,
                        ((int)HttpStatusCode.Forbidden).ToString(),
                        nameof(HttpStatusCode.Forbidden));
                    context.ReportError(error);
                }

                return;
            });
        });
    }
}

From your suggestion I added the above - but it seems a little heavy handed since it's going to run over everything in the case it's not there.

Is there a more efficient approach?

Is this better than or is there a downside to a string check on:

if(myquery.IndexOf("__schema",StringComparison.InvariantCultureIgnoreCase) >= 0)
//Stop processing

ExecutionResult result = await _executer.ExecuteAsync(_ =>
{
...
_.Query = myquery;
...
}

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024

Fair enough, but is that a real world false positive someone would run into?
I can't recall any instance I've ever include double underscore in a property.

Or really my question, is doing a string check somehow less secure in this instance?
Is there someway it could be skirted?

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024

Thanks for clarifying!!

from authorization.

AndyEdmonds avatar AndyEdmonds commented on July 1, 2024

What if I just want to leave out bits of schema that a particular user shouldn't see given their authorization status? Does returning forbidden play well with playground, voyager etc?

from authorization.

OpenSpacesAndPlaces avatar OpenSpacesAndPlaces commented on July 1, 2024

@AndyEdmonds

I don't know the right way to handle what you're saying, but the worst case would always be to pre-generate the schema - and create a separate controller for auth/loading separate copies.

Another possibility might be to modify something from "SchemaValidationRule : IValidationRule" above. Schema is one of the first matches you'd hit - so in-theory you could save that meta information to context.UserContext and then use that as a filter basis for other "IValidationRule" classes.

Both of these I would call 'hacks' to your problem.

from authorization.

AndyEdmonds avatar AndyEdmonds commented on July 1, 2024

Thanks @OpenSpacesAndPlaces,
In my case I've, perhaps foolishly, mixed functionality that is to do with maintenance of the site with functionality open to all and signed in users. I can happily stop users without the right authority from accessing things they shouldn't using .AuthorizeWith("UserPolicy"); but it can still be seen using schema discovery.
Perhaps I should move this functionality to a separate schema and serve two from the same source, if this is possible, perhaps serving something on say /graphql/admin
Alternatively adding annotation to the schema along the lines of deprecation might be good.

from authorization.

sungam3r avatar sungam3r commented on July 1, 2024

Closed as answered.

from authorization.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.