Skip to content

fix: block based on query operation name length#2090

Merged
SkArchon merged 16 commits intomainfrom
milinda/eng-7692-router-vulnerability-arbitrary-length-operation-name-enables
Jul 31, 2025
Merged

fix: block based on query operation name length#2090
SkArchon merged 16 commits intomainfrom
milinda/eng-7692-router-vulnerability-arbitrary-length-operation-name-enables

Conversation

@SkArchon
Copy link
Copy Markdown
Contributor

@SkArchon SkArchon commented Jul 29, 2025

This PR will trim the query op name based on the max size allocated.

Summary by CodeRabbit

  • New Features

    • Introduced a configurable limit for the maximum length of GraphQL operation names. Requests exceeding this limit are now rejected with an error.
    • Added configuration options to set or disable the operation name length limit via environment variables and configuration files.
  • Bug Fixes

    • Improved error handling for requests with excessively long operation names, ensuring proper error messages and HTTP status codes.
  • Tests

    • Added comprehensive tests to verify enforcement of the operation name length limit across various scenarios.

Checklist

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 29, 2025

Walkthrough

A maximum operation name length limit for GraphQL queries was introduced and enforced throughout the router. The change adds configuration options, schema validation, and runtime checks to reject queries with excessively long operation names. Tests were implemented to verify correct enforcement and configuration, including disabling the limit.

Changes

Cohort / File(s) Change Summary
Test Coverage: Operation Name Length Limit
router-tests/security_test.go
Added comprehensive tests for operation name length enforcement, covering various scenarios and configuration options.
Router Core: Enforcement and Propagation
router/core/graph_server.go, router/core/graphql_prehandler.go, router/core/operation_processor.go
Introduced and propagated OperationNameLengthLimit through core structs and logic. Added validation and error handling to reject operations exceeding the configured name length limit.
Configuration: Structs, Schema, and Defaults
router/pkg/config/config.go, router/pkg/config/config.schema.json, router/pkg/config/testdata/config_defaults.json, router/pkg/config/testdata/config_full.json, router/pkg/config/fixtures/full.yaml
Added OperationNameLengthLimit to configuration structs, schema, and test fixtures. Updated defaults and extended configuration files to include the new field.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • The changes introduce a new configuration field and propagate it through core logic, with multiple validation points and comprehensive tests. The logic is straightforward but touches several layers and requires careful review of both enforcement and configuration handling.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6d6013 and 9f8e0ec.

📒 Files selected for processing (2)
  • router/core/graphql_prehandler.go (1 hunks)
  • router/core/operation_processor.go (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • router/core/graphql_prehandler.go
  • router/core/operation_processor.go
⏰ 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). (8)
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: build_test
  • GitHub Check: Analyze (go)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch milinda/eng-7692-router-vulnerability-arbitrary-length-operation-name-enables

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@SkArchon SkArchon force-pushed the milinda/eng-7692-router-vulnerability-arbitrary-length-operation-name-enables branch from ed30639 to 105ba53 Compare July 30, 2025 09:13
@SkArchon SkArchon marked this pull request as ready for review July 30, 2025 09:13
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jul 30, 2025

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-7d120862558d4a30c1d75c906f02dd64354eab0d-nonroot

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
router/core/context.go (1)

536-538: Add accessor or remove unused operationTrimLimit

The field is private and never referenced inside context.go.
If other packages need it they will rely on direct struct access, leaking implementation details. Provide an accessor or use the value internally; otherwise the extra memory is wasted.

+// OperationNameTrimLimit returns the configured trim limit for this operation.
+func (o *operationContext) OperationNameTrimLimit() int {
+	return o.operationTrimLimit
+}

Alternatively, drop the field if trimming occurs earlier.

router/core/graphql_prehandler.go (1)

243-246: Avoid leaking internal OperationProcessor fields

h.operationProcessor.operationNameTrimLimit uses an un-exported field from OperationProcessor, tightly coupling PreHandler to OperationProcessor’s internal layout.
Expose the value via an accessor (e.g. OperationNameTrimLimit() int) or make the struct field exported to keep the boundary clean.

- operationTrimLimit: h.operationProcessor.operationNameTrimLimit,
+ operationTrimLimit: h.operationProcessor.OperationNameTrimLimit(),
router/core/operation_planner.go (1)

56-68: Consider edge cases and potential performance impact.

The implementation looks correct for basic trimming functionality, but there are a few concerns:

  1. Performance: The loop iterates through all root nodes on every parse, even when trimming isn't needed. Consider adding an early exit condition when ctx.operationTrimLimit <= 0 or is set to a very large value.

  2. Edge case: The code assumes GetOperationNameTrimmed always returns valid results, but there's no validation of the trim limit value itself.

Consider optimizing with an early exit:

+	// Skip trimming logic if no limit is set or limit is very large
+	if ctx.operationTrimLimit <= 0 || ctx.operationTrimLimit >= 1000000 {
+		// Skip trimming for unlimited or very large limits
+	} else {
		// The doc is parsed using ctx.content which is the normalized content from the original parsed content
		// This contains the original operation name, so we need to manually tell the parser to ignore the
		// extra parts
		for i := range doc.RootNodes {
			if doc.RootNodes[i].Kind != ast.NodeKindOperationDefinition {
				continue
			}
			currName := doc.OperationDefinitionNameString(doc.RootNodes[i].Ref)
			if trimmed, _ := GetOperationNameTrimmed(currName, ctx.operationTrimLimit); trimmed {
				name := doc.OperationDefinitions[doc.RootNodes[i].Ref].Name
				doc.OperationDefinitions[doc.RootNodes[i].Ref].Name.End = name.Start + uint32(ctx.operationTrimLimit)
			}
		}
+	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 618d62b and 105ba53.

📒 Files selected for processing (10)
  • router-tests/security_test.go (2 hunks)
  • router/core/context.go (1 hunks)
  • router/core/graph_server.go (1 hunks)
  • router/core/graphql_prehandler.go (1 hunks)
  • router/core/operation_planner.go (1 hunks)
  • router/core/operation_processor.go (8 hunks)
  • router/pkg/config/config.go (1 hunks)
  • router/pkg/config/config.schema.json (1 hunks)
  • router/pkg/config/testdata/config_defaults.json (1 hunks)
  • router/pkg/config/testdata/config_full.json (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
router/pkg/config/testdata/config_defaults.json (2)

Learnt from: endigma
PR: #2009
File: router/pkg/config/config.go:0-0
Timestamp: 2025-07-03T10:33:25.778Z
Learning: The CardinalityLimit field in the Metrics struct (router/pkg/config/config.go) is validated at the JSON schema level in config.schema.json with a minimum value constraint of 1, preventing zero or negative values without requiring runtime validation.

Learnt from: SkArchon
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.

router/pkg/config/testdata/config_full.json (3)

Learnt from: SkArchon
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.

Learnt from: endigma
PR: #2009
File: router/pkg/config/config.go:0-0
Timestamp: 2025-07-03T10:33:25.778Z
Learning: The CardinalityLimit field in the Metrics struct (router/pkg/config/config.go) is validated at the JSON schema level in config.schema.json with a minimum value constraint of 1, preventing zero or negative values without requiring runtime validation.

Learnt from: SkArchon
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.

router/pkg/config/config.go (1)

Learnt from: endigma
PR: #2009
File: router/pkg/config/config.go:0-0
Timestamp: 2025-07-03T10:33:25.778Z
Learning: The CardinalityLimit field in the Metrics struct (router/pkg/config/config.go) is validated at the JSON schema level in config.schema.json with a minimum value constraint of 1, preventing zero or negative values without requiring runtime validation.

router/core/graph_server.go (1)

Learnt from: endigma
PR: #2009
File: router/pkg/config/config.go:0-0
Timestamp: 2025-07-03T10:33:25.778Z
Learning: The CardinalityLimit field in the Metrics struct (router/pkg/config/config.go) is validated at the JSON schema level in config.schema.json with a minimum value constraint of 1, preventing zero or negative values without requiring runtime validation.

router/pkg/config/config.schema.json (4)

Learnt from: endigma
PR: #2009
File: router/pkg/config/config.go:0-0
Timestamp: 2025-07-03T10:33:25.778Z
Learning: The CardinalityLimit field in the Metrics struct (router/pkg/config/config.go) is validated at the JSON schema level in config.schema.json with a minimum value constraint of 1, preventing zero or negative values without requiring runtime validation.

Learnt from: SkArchon
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.

Learnt from: SkArchon
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.

Learnt from: SkArchon
PR: #1929
File: router/internal/circuit/manager.go:16-25
Timestamp: 2025-06-30T20:39:02.387Z
Learning: In the Cosmo router project, parameter validation for circuit breaker configuration is handled at the JSON schema level rather than through runtime validation methods on structs. The config.schema.json file contains comprehensive validation constraints for circuit breaker parameters.

⏰ 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). (12)
  • GitHub Check: build-router
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: image_scan
  • GitHub Check: build_push_image
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_test
🔇 Additional comments (12)
router/pkg/config/testdata/config_full.json (1)

675-679: JSON example misses context comment or schema alignment check

The sample adds OperationNameTrimLimit directly under SecurityConfiguration, which matches the Go struct. 🆗
Please make sure the generated JSON schema already permits this property at that path; otherwise this file will fail validation in CI.

router/pkg/config/testdata/config_defaults.json (1)

315-320: Keep defaults file in sync with schema

Same remark as above: ensure the new field is present in config.schema.json with the same default so that config_defaults.json remains a valid instance.
No other issues spotted.

router/core/graph_server.go (1)

1208-1212: No overflow concern: OperationNameTrimLimit is already a Go int
The OperationNameTrimLimit field in router/pkg/config/config.go is declared as an int (line 411), so casting it with int(...) is a no-op and cannot overflow at runtime. There’s no JSON-schema constraint on this field, but any out-of-range value would fail during YAML/env parsing before you ever reach this assignment. You can safely ignore the overflow-guard suggestion (or simply drop the redundant cast).

Likely an incorrect or invalid review comment.

router-tests/security_test.go (3)

4-7: LGTM!

The import additions for OpenTelemetry tracing and metrics support are appropriate for the new test functionality.


117-201: Comprehensive test coverage with good edge case handling.

The test implementation covers the three critical scenarios effectively:

  1. Trimming when over the limit
  2. No trimming when exactly at the limit
  3. No trimming when under the limit

The use of tracing spans to verify the operation name is a solid approach for end-to-end validation.

However, consider adding a test case for zero or negative trim limits to ensure robust error handling:

t.Run("verify that zero trim limit handles gracefully", func(t *testing.T) {
    // Test with trimSize = 0
})

203-210: Simple and effective helper function.

The helper function correctly extracts the operation name attribute from the OpenTelemetry attributes slice.

router/core/operation_processor.go (6)

119-119: LGTM!

Addition of OperationNameTrimLimit field to the options struct is straightforward and follows the existing pattern.


135-135: LGTM!

Addition of the trim limit field to the processor struct is consistent with the design pattern.


260-260: Consistent application of trimming in URL unmarshaling.

The trimming is correctly applied when unmarshaling operation names from URL parameters.


383-385: Consistent trimming application in body unmarshaling.

The trimming logic is correctly applied when the operation name is not null.


596-596: Correct usage of trimming function in parsing.

The trimming is applied consistently during the parsing phase.


1279-1279: LGTM!

The processor initialization correctly assigns the trim limit from the options.

Comment thread router/core/operation_processor.go Outdated
Comment thread router/core/operation_processor.go Outdated
Comment thread router/pkg/config/config.go Outdated
Comment thread router/pkg/config/config.schema.json Outdated
Comment thread router/core/operation_planner.go
@SkArchon SkArchon changed the title fix: trim query operation name length [WIP] fix: trim query operation name length Jul 30, 2025
Comment thread router/core/operation_processor.go Outdated
Comment thread router/core/operation_planner.go Outdated
Comment thread router/pkg/config/config.go Outdated
Comment thread router/pkg/config/config.schema.json Outdated
Comment thread router-tests/security_test.go Outdated
Comment thread router-tests/security_test.go Outdated
Comment thread router/core/context.go Outdated
Comment thread router/core/operation_processor.go Outdated
@SkArchon SkArchon marked this pull request as draft July 30, 2025 11:17
@SkArchon SkArchon changed the title fix: trim query operation name length fix: block based on query operation name length [WIP] Jul 30, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Jul 30, 2025
5 tasks
@SkArchon SkArchon changed the title fix: block based on query operation name length [WIP] fix: block based on query operation name length Jul 30, 2025
@SkArchon SkArchon marked this pull request as ready for review July 30, 2025 13:51
Comment thread router/core/operation_processor.go Outdated
Comment thread router/core/operation_processor.go Outdated
Comment thread router/pkg/config/config.go Outdated
Comment thread router/pkg/config/config.schema.json Outdated
Comment thread router-tests/security_test.go Outdated
Copy link
Copy Markdown
Contributor

@StarpTech StarpTech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@SkArchon SkArchon requested a review from endigma July 30, 2025 18:48
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
router-tests/security_test.go (2)

217-217: Fix typo in variable name.

There's a typo in the variable name liitSize which should be limitSize or similar.

-			liitSize := 7
+			limitSize := 7

Also update the usage on line 224:

-					securityConfiguration.OperationNameLengthLimit = liitSize
+					securityConfiguration.OperationNameLengthLimit = limitSize

303-303: Fix typo in test name.

There's a typo "ebaled" which should be "enabled".

-		t.Run("with large queries with max length of 0 where the validation is not ebaled", func(t *testing.T) {
+		t.Run("with large queries with max length of 0 where the validation is not enabled", func(t *testing.T) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 199447f and 9855ed2.

📒 Files selected for processing (1)
  • router-tests/security_test.go (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: SkArchon
PR: wundergraph/cosmo#2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.
Learnt from: SkArchon
PR: wundergraph/cosmo#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.
router-tests/security_test.go (2)

Learnt from: SkArchon
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.

Learnt from: SkArchon
PR: #2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.

⏰ 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: build-router
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: image_scan
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./events)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: build_test
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
router-tests/security_test.go (8)

4-5: LGTM - Import additions are appropriate.

The fmt package is needed for string formatting in the test assertions, and the core package is required for router options configuration.


115-147: Test logic and structure look good.

The first subtest correctly validates that queries with operation names exceeding the limit are rejected with appropriate error messages for both POST and GET requests.


149-179: Test correctly validates query name takes precedence over operation name parameter.

This subtest properly demonstrates that when both query name and operation name are present, the query name from the GraphQL document is used for length validation, not the operation name parameter.


181-212: Test correctly validates operation name parameter when query name is short.

This subtest properly demonstrates that when the query name is within limits but the operation name parameter exceeds the limit, the operation name parameter length is enforced.


214-243: Test correctly validates successful requests within limits.

This subtest properly demonstrates that requests with operation names within the configured limit are processed successfully.


245-273: Test correctly validates multiple operations with one exceeding limit.

This subtest properly demonstrates that when multiple operations are present and one exceeds the limit, the request is rejected with the appropriate error message.


275-301: Test correctly validates multiple operations within limits.

This subtest properly demonstrates that requests with multiple operations all within the configured limit are processed successfully.


303-329: Test correctly validates disabled validation (limit = 0).

This subtest properly demonstrates that when the limit is set to 0, validation is disabled and requests with long operation names are processed successfully.

Comment thread router-tests/security_test.go
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

♻️ Duplicate comments (3)
router-tests/security_test.go (3)

214-243: LGTM with minor typo fix!

This subtest correctly validates the successful case where both query and operation names are within the length limit. The test properly expects HTTP 200 status and valid data response.


303-329: LGTM with typo fix!

This subtest correctly validates that setting the limit to 0 disables the validation, allowing operations with long names to execute successfully. This is an important edge case test.


332-363: Test correctly validates operation name limits with introspection disabled.

This subtest properly verifies that operation name length validation works even when introspection is disabled. The test correctly configures router options and validates the expected behavior.

🧹 Nitpick comments (2)
router-tests/security_test.go (2)

217-217: Fix the typo in variable name.

-			liitSize := 7
+			limitSize := 7

303-303: Fix the typo in test name.

-		t.Run("with large queries with max length of 0 where the validation is not ebaled", func(t *testing.T) {
+		t.Run("with large queries with max length of 0 where the validation is not enabled", func(t *testing.T) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9855ed2 and 9a2c9a3.

📒 Files selected for processing (1)
  • router-tests/security_test.go (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: SkArchon
PR: wundergraph/cosmo#2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.
Learnt from: SkArchon
PR: wundergraph/cosmo#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.
router-tests/security_test.go (2)

Learnt from: SkArchon
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.

Learnt from: SkArchon
PR: #2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.

⏰ 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). (12)
  • GitHub Check: build-router
  • GitHub Check: image_scan
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: integration_test (./events)
  • GitHub Check: build_test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
  • GitHub Check: build_test
🔇 Additional comments (6)
router-tests/security_test.go (6)

4-5: LGTM!

The added imports fmt and github.com/wundergraph/cosmo/router/core are correctly used in the new test function for string formatting and router options configuration.


115-147: LGTM!

The first subtest correctly validates operation name length limits when no operation name is explicitly provided. The test logic properly checks both POST and GET methods with consistent error message validation.


149-179: LGTM!

This subtest correctly validates that the query name length is checked even when a smaller operation name is provided. The test demonstrates that the query name takes precedence for validation, which aligns with the expected behavior.


181-212: LGTM!

This subtest properly validates operation name length limits when the operation name exceeds the limit. The test correctly uses the operation name length for error message validation.


245-273: LGTM!

This subtest correctly validates that when multiple operations are present in a query, the validation properly identifies and rejects operations that exceed the length limit. The error message correctly identifies the specific operation that violates the limit.


275-301: LGTM!

This subtest properly validates the successful case where multiple operations are present but all operation names are within the length limit. The test correctly expects successful execution.

Copy link
Copy Markdown
Member

@endigma endigma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

Comment thread router-tests/security_test.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

♻️ Duplicate comments (1)
router-tests/security_test.go (1)

332-363: Inconsistent query types within the same subtest.

The POST and GET requests use introspection queries (__schema { __typename }) while introspection is disabled. For consistency and clearer test intent, consider using regular queries instead.

Since this test is about verifying that operation name length limits work even when introspection is disabled, both requests should use regular queries:

				resPost, err := xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{
-					Query: "query " + query1Name + " { __schema { __typename } } query " + query2Name + " { employees { id } }",
+					Query: "query " + query1Name + " { employees { id } } query " + query2Name + " { employees { id } }",
				})

This makes the test focus solely on operation name length validation rather than mixing introspection concerns.

🧹 Nitpick comments (1)
router-tests/security_test.go (1)

217-217: Fix the typo in variable name.

Variable name liitSize should be limitSize.

- liitSize := 7
+ limitSize := 7

And update its usage on line 224:

- securityConfiguration.OperationNameLengthLimit = liitSize
+ securityConfiguration.OperationNameLengthLimit = limitSize
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4c5b6c and e6d6013.

📒 Files selected for processing (2)
  • router-tests/security_test.go (2 hunks)
  • router-tests/testenv/testenv.go (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: SkArchon
PR: wundergraph/cosmo#2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.
Learnt from: SkArchon
PR: wundergraph/cosmo#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.
router-tests/security_test.go (2)

Learnt from: SkArchon
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.

Learnt from: SkArchon
PR: #2090
File: router/core/operation_processor.go:0-0
Timestamp: 2025-07-30T09:29:04.257Z
Learning: GraphQL operation names don't allow characters with more than 1 code point, so string length operations and slicing work correctly for both byte and character counting in GraphQL operation name processing.

router-tests/testenv/testenv.go (1)

Learnt from: SkArchon
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.

⏰ 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: build-router
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: image_scan
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_test
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
router-tests/testenv/testenv.go (1)

1328-1339: LGTM! Clean implementation of default security configuration.

The wrapper pattern correctly ensures that OperationNameLengthLimit is always set to 512 while preserving any custom security configuration logic. This provides consistent test behavior for the new operation name length limit feature.

router-tests/security_test.go (8)

5-5: LGTM! Import needed for router configuration options.

The import is correctly added to support the core.Option and core.WithIntrospection(false) usage in the test.


115-117: LGTM! Proper test function structure.

The test function follows Go testing conventions with parallel execution enabled.


121-147: LGTM! Comprehensive test for query name length validation.

The test properly validates that operation names exceeding the limit are rejected with appropriate error messages for both POST and GET requests.


149-179: LGTM! Validates query name prioritization over operation name parameter.

The test correctly verifies that the system validates the actual query name from the GraphQL document rather than just the explicit operation name parameter.


181-212: LGTM! Validates operation name parameter length checking.

The test properly verifies that explicit operation names are also subject to length validation, demonstrating comprehensive coverage of both query names and operation name parameters.


245-273: LGTM! Validates multiple operation parsing with length limits.

The test properly verifies that operation name length validation works correctly when parsing multiple operations in a single GraphQL document.


275-301: LGTM! Validates success path for multiple valid operations.

The test correctly verifies that multiple operations within the length limit are processed successfully.


303-329: LGTM! Validates disabled validation behavior.

The test correctly verifies that setting OperationNameLengthLimit to 0 disables the validation, ensuring backwards compatibility.

@SkArchon SkArchon merged commit 3d924a4 into main Jul 31, 2025
38 of 39 checks passed
@SkArchon SkArchon deleted the milinda/eng-7692-router-vulnerability-arbitrary-length-operation-name-enables branch July 31, 2025 09:59
@Noroth Noroth mentioned this pull request Sep 30, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants