Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding ModifyPagingOptions causes the follow error: "The maximum allowed type cost was exceeded" #7763

Closed
msheluga opened this issue Nov 25, 2024 · 11 comments

Comments

@msheluga
Copy link

Product

Hot Chocolate

Version

14.10

Link to minimal reproduction

https://github.com/msheluga/HC14Test

Steps to reproduce

the project does require the Adventureworks2022 DB which is located at https://learn.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=ssms

  • when the graphql server is running execute the following query
    `query {
    address(order: [{ addressID: ASC }]) {
    nodes {
    addressID

    city
    

    }
    }
    }
    `
    error will occur

What is expected?

pagination to function as it did in V13 where the SetPagingOptions modified the paging attributes without errors about the cost. It should return 100 records .

What is actually happening?

Modifying the Paging options as described in the documentation causes the following message
"message": "The maximum allowed type cost was exceeded."
this also occurs if you modify the DefaultPagingSize in the attribute i.e. [UsePaging (DefaultPageSize =100)]
if all paging is removed it will return all 32521 records

Relevant log output

Additional context

No response

@sajmonr
Copy link

sajmonr commented Dec 3, 2024

I had similar issue and, after reading up on it, this does not seem like a bug but more like intended behavior of v14 protecting against unsafe queries. This helped me identify several of my queries that had the potential to break the app. I'm guessing in your case changing the pagination increases the assumed list size which causes it to be larger than the default type cost of 1000.

The best way to debug your query is to send a header GraphQL-cost=report which will show you the actual cost of various queries and then trim your queries accordingly. If you cannot do that then you will need to increase the default type cost to something more suitable for you.

builder
    .AddGraphQL()
    .ModifyCostOptions(o =>
    {
        // Set the limit depending on your needs
        o.MaxTypeCost = 4000;
    })

Alternatively, you could disable the cost enforcement, however, it is not recommend doing that. Also, remember that setting the max cost too high is effectively turning it off.

@michaelstaib
Copy link
Member

Yes ... also setting the max paging amount too high is effectively allowing everyone to ask for this amount. The GraphQL cost just tells you about common API design mistakes.

@msheluga
Copy link
Author

msheluga commented Dec 4, 2024

We need it to be able to return more then 10 records. how do we increase the complexity limit now with the new complexity calculator?

@sajmonr
Copy link

sajmonr commented Dec 4, 2024

When it throws the error it should tell you the cost of your query. Then change the max cost in program.cs using the options that I posted in my earlier comment to something larger.

@msheluga
Copy link
Author

msheluga commented Dec 4, 2024

my apologizes for not stating my issue clearly. In our production system I don't know the queries, since we host the data for multiple applications. So I could not even begin to go down that route and guess what to set the max cost to. From what I am seeing and reading I should just turn off the enforce cost limits.

@sajmonr
Copy link

sajmonr commented Dec 4, 2024

I guess you could also do the math on the worst case scenario for each query (max number of root items x max number of nested items x so on) but that could be tedious and lengthy process.

I assume if you can't reasonably predict the various sizes of the queries then turning the enforcement in the options would be your best bet to return the behavior to what it was in v13.

@msheluga
Copy link
Author

msheluga commented Dec 5, 2024

we used to do the following in 12 & 13
`ModifyRequestOptions(o =>
{
//sets maximum allowed complexity of a query
//by default each field is 1 complexity, arguments are used as multipliers
//possibly store in database for each application

            var complexitySection = config.GetSection("ComplexityOptions");

            o.Complexity.Enable = bool.TryParse(complexitySection["EnableComplexity"],
                                                    out bool enableComplexity)
                                        && enableComplexity;

            o.Complexity.MaximumAllowed = int.TryParse(complexitySection["MaxAllowed"],
                                                        out int maxComplexity)
                                            ? maxComplexity
                                            : 5000;
        });`

it appears that this isn't an option in 14 since it is all now cost and not complexity. It would appear that custom cost limits are very different then how it used to be.

I was able to make it work using the documentation, but the max field and max type costs are high enough that I wonder if it would be better to disable the cost. since in the example provided I was only showing one table paginated with only two fields.
The way it will be used in production will obviously be asking far more data and far more relations as well

@michaelstaib
Copy link
Member

The complexity can be configured like the following:

builder.Services
    .AddGraphQLServer()
    .ModifyCostOptions(options =>
    {
        options.MaxFieldCost = 1_000;
        options.MaxTypeCost = 1_000;
        options.EnforceCostLimits = true;
        options.ApplyCostDefaults = true;
        options.DefaultResolverCost = 10.0;
    });

You can find the docs here:
https://chillicream.com/docs/hotchocolate/v14/security/cost-analysis

@michaelstaib
Copy link
Member

The basic question you have to ask yourself is how you secure your endpoint. You have 2 options:

  1. trusted documents aka persisted operations
  2. complexity analyzer

I can recommend watching the following talk on GraphQL security:
https://www.youtube.com/watch?v=Ytt1_ZIlYdg

@michaelstaib
Copy link
Member

Closing this issue as its not a bug but rather a question.

@michaelstaib
Copy link
Member

BTW you can join our slack channel for discussions:
https://slack.chillicream.com

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

No branches or pull requests

3 participants