-
Notifications
You must be signed in to change notification settings - Fork 192
fix: omit introspection queries for complexity limits #2296
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
base: main
Are you sure you want to change the base?
fix: omit introspection queries for complexity limits #2296
Conversation
Introspection queries are not considered when calculating complexity limits.
WalkthroughAdded tests and configuration to control skipping complexity checks for GraphQL introspection; refactored complexity-check plumbing to use a local limits variable; added Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Potential attention points:
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
Comment |
Router-nonroot image scan passed✅ No security vulnerabilities found in image: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
router-tests/complexity_limits_test.go (1)
59-133: Excellent test coverage for introspection bypass.This test effectively validates that introspection queries bypass complexity limits. The test uses a depth limit of 1 but runs an introspection query with 7+ levels of nesting, clearly demonstrating the bypass behavior.
Consider adding a companion assertion within this test to verify that regular queries still respect the depth limit when introspection is enabled:
// After the introspection query succeeds, verify regular queries still blocked res2, _ := xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ Query: `{ employee(id:1) { id details { forename } } }`, }) require.Equal(t, 400, res2.Response.StatusCode) require.Contains(t, res2.Body, "exceeds the max query depth allowed")This would provide more confidence that the introspection bypass doesn't accidentally disable depth limits for all queries.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
router-tests/go.sumis excluded by!**/*.sumrouter/go.sumis excluded by!**/*.sum
📒 Files selected for processing (3)
router-tests/complexity_limits_test.go(2 hunks)router-tests/go.mod(1 hunks)router/go.mod(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T22:13:25.222Z
Learnt from: StarpTech
PR: wundergraph/cosmo#2157
File: router-tests/go.mod:16-16
Timestamp: 2025-08-20T22:13:25.222Z
Learning: github.com/mark3labs/mcp-go v0.38.0 has regressions and should not be used in the wundergraph/cosmo project. v0.36.0 is the stable version that should be used across router-tests and other modules.
Applied to files:
router-tests/go.mod
🧬 Code graph analysis (1)
router-tests/complexity_limits_test.go (3)
router-tests/testenv/testenv.go (4)
Run(105-122)Config(284-341)Environment(1729-1765)GraphQLRequest(1905-1913)router/pkg/config/config.go (3)
Config(1000-1074)SecurityConfiguration(410-420)QueryDepthConfiguration(427-432)router/core/router.go (2)
Option(172-172)WithIntrospection(1539-1543)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: image_scan
- GitHub Check: Analyze (go)
- GitHub Check: build_push_image
- GitHub Check: build_push_image (nonroot)
- GitHub Check: integration_test (./telemetry)
- GitHub Check: image_scan (nonroot)
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: integration_test (./events)
- GitHub Check: build_test
- GitHub Check: build_test
🔇 Additional comments (3)
router/go.mod (1)
34-34: LGTM! Dependency version consistent with router-tests.The version bump matches the update in
router-tests/go.mod, maintaining consistency across modules.router-tests/complexity_limits_test.go (1)
10-10: LGTM! Import necessary for introspection option.The
corepackage import is required to usecore.WithIntrospection(true)in the new test case.router-tests/go.mod (1)
30-30: Feature is implemented and tested; however, note RC pre-release status.The version rc.233 was released today (2025-10-23) and includes the implementation for excluding introspection queries from complexity limits, as confirmed by the git history showing the commit "fix: omit introspection queries for complexity limits" as the most recent go.mod change. The test
"allows introspection queries without limits"incomplexity_limits_test.govalidates this functionality by setting a depth limit of 1 and confirming an introspection query succeeds despite the constraint.That said, rc.233 is a pre-release (RC status), not a stable release. Consider whether a pre-release version is appropriate for your deployment environment, or plan to upgrade to a stable version (e.g., v2.0.0) once available.
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
…6-omit-introspection-queries-from-complexity-limits
…6-omit-introspection-queries-from-complexity-limits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
router/core/operation_processor.go (1)
1162-1191: Don’t reuse complexity cache entries across SkipIntrospection flipsWhen
SkipIntrospectionis true we now drop the complexity for introspection documents, but we still cache that zeroedComplexityCacheEntry. If an operator later disablesSkipIntrospection, the cached entry (still keyed only byInternalID) is returned here and we never recompute, so the introspection operation keeps sailing through the limits despite the config change. That violates the expected guard until the cache is manually flushed or evicted, effectively disabling the limit.Please include the skip flag in the cache identity (or bypass caching altogether while skipping) so toggling the option forces a fresh computation. For example:
-type ComplexityCacheEntry struct { - Depth int - TotalFields int - RootFields int - RootFieldAliases int -} +type ComplexityCacheEntry struct { + Depth int + TotalFields int + RootFields int + RootFieldAliases int + SkipIntrospection bool +} @@ - if o.cache != nil && o.cache.complexityCache != nil { - if cachedComplexity, found := o.cache.complexityCache.Get(o.parsedOperation.InternalID); found { - return true, cachedComplexity, o.runComplexityComparisons(limits, cachedComplexity, o.parsedOperation.IsPersistedOperation) - } - } + if o.cache != nil && o.cache.complexityCache != nil { + if cachedComplexity, found := o.cache.complexityCache.Get(o.parsedOperation.InternalID); found && cachedComplexity.SkipIntrospection == limits.SkipIntrospection { + return true, cachedComplexity, o.runComplexityComparisons(limits, cachedComplexity, o.parsedOperation.IsPersistedOperation) + } + } @@ - cacheResult := ComplexityCacheEntry{ - Depth: globalComplexityResult.Depth, - TotalFields: globalComplexityResult.NodeCount, - } + cacheResult := ComplexityCacheEntry{ + Depth: globalComplexityResult.Depth, + TotalFields: globalComplexityResult.NodeCount, + SkipIntrospection: limits.SkipIntrospection, + }
🧹 Nitpick comments (2)
router/pkg/config/config.schema.json (1)
2599-2604: Good placement; fix tiny description typo.Property is correctly added under security.complexity_limits. Tweak wording.
Apply:
- "description": "Set to to true to skip introspection queries when calculating complexity limits." + "description": "Set to true to skip introspection queries when calculating complexity limits."router/pkg/config/config.go (1)
440-445: Field addition aligns with schema; consider a brief doc comment.Add a short comment to clarify scope (applies to all complexity checks).
type ComplexityLimits struct { - Depth *ComplexityLimit `yaml:"depth"` - TotalFields *ComplexityLimit `yaml:"total_fields"` - RootFields *ComplexityLimit `yaml:"root_fields"` - RootFieldAliases *ComplexityLimit `yaml:"root_field_aliases"` - SkipIntrospection bool `yaml:"skip_introspection" envDefault:"false"` + Depth *ComplexityLimit `yaml:"depth"` + TotalFields *ComplexityLimit `yaml:"total_fields"` + RootFields *ComplexityLimit `yaml:"root_fields"` + RootFieldAliases *ComplexityLimit `yaml:"root_field_aliases"` + // When true, introspection operations are excluded from all complexity checks. + SkipIntrospection bool `yaml:"skip_introspection" envDefault:"false"` }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
router-tests/go.sumis excluded by!**/*.sumrouter/go.sumis excluded by!**/*.sum
📒 Files selected for processing (8)
router-tests/complexity_limits_test.go(2 hunks)router-tests/go.mod(1 hunks)router/core/operation_processor.go(2 hunks)router/core/router.go(1 hunks)router/go.mod(1 hunks)router/pkg/config/config.go(2 hunks)router/pkg/config/config.schema.json(1 hunks)router/pkg/config/testdata/config_full.json(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- router/go.mod
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2252
File: router-tests/telemetry/telemetry_test.go:9684-9693
Timestamp: 2025-10-01T20:39:16.113Z
Learning: Repo preference: In router-tests/telemetry/telemetry_test.go, keep strict > 0 assertions for request.operation.*Time (parsingTime, normalizationTime, validationTime, planningTime) in telemetry-related tests; do not relax to >= 0 unless CI flakiness is observed.
📚 Learning: 2025-09-29T10:28:07.122Z
Learnt from: dkorittki
Repo: wundergraph/cosmo PR: 2192
File: router/pkg/config/config.go:1028-1029
Timestamp: 2025-09-29T10:28:07.122Z
Learning: The deprecation strategy for IntrospectionEnabled field in router/pkg/config/config.go is to first mark it as deprecated, then migrate all call sites to use IntrospectionConfig.Enabled, and finally remove the deprecated field. The envDefault tag should be kept during the deprecation period for backward compatibility.
Applied to files:
router/pkg/config/config.gorouter/core/router.go
📚 Learning: 2025-08-28T09:59:19.999Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2167
File: router/core/supervisor_instance.go:196-204
Timestamp: 2025-08-28T09:59:19.999Z
Learning: In router/pkg/config/config.go, the BackoffJitterRetry struct uses envDefault tags to provide default values for Algorithm ("backoff_jitter") and Expression ("IsRetryableStatusCode() || IsConnectionError() || IsTimeout()"), ensuring that even when YAML configs omit these fields, valid defaults are applied automatically, preventing ProcessRetryOptions from rejecting empty values.
Applied to files:
router/pkg/config/config.go
📚 Learning: 2025-07-30T09:29:46.660Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2090
File: router/pkg/config/config.schema.json:0-0
Timestamp: 2025-07-30T09:29:46.660Z
Learning: The "operation_name_trim_limit" configuration property in router/pkg/config/config.schema.json should be placed at the security level as a sibling to complexity_limits, not inside the complexity_limits object.
Applied to files:
router/pkg/config/config.gorouter/core/router.gorouter/core/operation_processor.gorouter/pkg/config/config.schema.jsonrouter/pkg/config/testdata/config_full.json
📚 Learning: 2025-07-21T15:06:36.664Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/config/config.schema.json:1637-1644
Timestamp: 2025-07-21T15:06:36.664Z
Learning: In the Cosmo router project, when extending JSON schema validation for security-sensitive fields like JWKS secrets, backwards compatibility is maintained by implementing warnings in the Go code rather than hard validation constraints in the schema. This allows existing configurations to continue working while alerting users to potential security issues.
Applied to files:
router/core/router.gorouter/pkg/config/config.schema.jsonrouter/pkg/config/testdata/config_full.json
📚 Learning: 2025-08-20T22:13:25.222Z
Learnt from: StarpTech
Repo: wundergraph/cosmo PR: 2157
File: router-tests/go.mod:16-16
Timestamp: 2025-08-20T22:13:25.222Z
Learning: github.com/mark3labs/mcp-go v0.38.0 has regressions and should not be used in the wundergraph/cosmo project. v0.36.0 is the stable version that should be used across router-tests and other modules.
Applied to files:
router-tests/go.modrouter-tests/complexity_limits_test.go
📚 Learning: 2025-10-01T20:39:16.113Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2252
File: router-tests/telemetry/telemetry_test.go:9684-9693
Timestamp: 2025-10-01T20:39:16.113Z
Learning: Repo preference: In router-tests/telemetry/telemetry_test.go, keep strict > 0 assertions for request.operation.*Time (parsingTime, normalizationTime, validationTime, planningTime) in telemetry-related tests; do not relax to >= 0 unless CI flakiness is observed.
Applied to files:
router-tests/go.modrouter-tests/complexity_limits_test.go
📚 Learning: 2025-09-24T12:54:00.765Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2222
File: router-tests/websocket_test.go:2238-2302
Timestamp: 2025-09-24T12:54:00.765Z
Learning: The wundergraph/cosmo project uses Go 1.25 (Go 1.23+ minimum), so fmt.Appendf and other newer Go standard library functions are available and can be used without compatibility concerns.
Applied to files:
router-tests/go.mod
📚 Learning: 2025-09-24T12:54:00.765Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2222
File: router-tests/websocket_test.go:2238-2302
Timestamp: 2025-09-24T12:54:00.765Z
Learning: The wundergraph/cosmo project uses Go 1.25 (Go 1.25 minimum), so fmt.Appendf and other newer Go standard library functions are available and can be used without compatibility concerns.
Applied to files:
router-tests/go.mod
📚 Learning: 2025-08-15T10:21:45.838Z
Learnt from: StarpTech
Repo: wundergraph/cosmo PR: 2142
File: helm/cosmo/Chart.yaml:0-0
Timestamp: 2025-08-15T10:21:45.838Z
Learning: In the WunderGraph Cosmo project, helm chart version upgrades and README badge synchronization are handled in separate helm release PRs, not in the initial version bump PRs.
Applied to files:
router-tests/go.mod
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: router/pkg/config/config.schema.json forbids null values for traffic_shaping.subgraphs: additionalProperties references $defs.traffic_shaping_subgraph_request_rule with type "object". Therefore, in core.NewSubgraphTransportOptions, dereferencing each subgraph rule pointer is safe under schema-validated configs, and a nil-check is unnecessary.
Applied to files:
router/pkg/config/config.schema.json
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: In the Cosmo router codebase, JSON schema validation prevents null values in TrafficShapingRules subgraph configurations, making nil checks unnecessary when dereferencing subgraph rule pointers in NewSubgraphTransportOptions.
Applied to files:
router/pkg/config/config.schema.json
📚 Learning: 2025-08-28T09:17:49.477Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2141
File: router-tests/http_subscriptions_test.go:17-55
Timestamp: 2025-08-28T09:17:49.477Z
Learning: The Cosmo router uses a custom, intentionally rigid multipart implementation for GraphQL subscriptions. The multipart parsing in test files should remain strict and not be made more tolerant, as this rigidity is by design.
Applied to files:
router-tests/complexity_limits_test.go
📚 Learning: 2025-07-21T14:46:34.879Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2067
File: router/pkg/authentication/jwks_token_decoder.go:80-106
Timestamp: 2025-07-21T14:46:34.879Z
Learning: In the Cosmo router project, required field validation for JWKS configuration (Secret, Algorithm, KeyId) is handled at the JSON schema level in config.schema.json rather than through runtime validation in the Go code at router/pkg/authentication/jwks_token_decoder.go.
Applied to files:
router/pkg/config/testdata/config_full.json
🧬 Code graph analysis (1)
router-tests/complexity_limits_test.go (3)
router-tests/testenv/testenv.go (4)
Run(105-122)Config(284-341)Environment(1731-1767)GraphQLRequest(1907-1915)router/pkg/config/config.go (5)
Config(1007-1082)IntrospectionConfiguration(1002-1005)SecurityConfiguration(410-420)ComplexityLimits(439-445)ComplexityLimit(447-451)router/core/router.go (2)
Option(172-172)WithIntrospection(1548-1553)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: build_test
- GitHub Check: build_push_image (nonroot)
- GitHub Check: image_scan (nonroot)
- GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
- GitHub Check: integration_test (./events)
- GitHub Check: build_test
- GitHub Check: build_push_image
- GitHub Check: integration_test (./telemetry)
- GitHub Check: image_scan
🔇 Additional comments (3)
router/pkg/config/testdata/config_full.json (1)
712-714: Config sample update matches new field.The sample adds SkipIntrospection at the correct location and casing. LGTM.
router/pkg/config/config.go (1)
453-455: ApplyLimit logic is correct.Condition simplifies to “enabled and not (persistent AND ignorePersisted)”. No issues.
router-tests/go.mod (1)
30-30: Dependency bump verified and cross-module alignment confirmed.Both
router/go.modandrouter-tests/go.modpoint to the same graphql-go-tools/v2 version (v2.0.0-rc.237.0.20251111144341-5d93cce1da45), ensuring consistent planner/parser behavior across modules.
Introspection queries are not considered when calculating complexity limits.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores