Mitigation Strategy: Query Complexity Limitation and Analysis
Description:
- Assign Complexity Values (with
gqlgen
): Usegqlgen
's support for complexity functions. Within your resolvers, access thegraphql.GetOperationContext(ctx).Stats.OperationComplexity
and increment it based on the complexity of the field being resolved. You can use directives in your schema (e.g.,@cost(value: 5)
) to define complexity and read those values in your resolvers. - Set a Complexity Limit (with
gqlgen
): In your server configuration (usinghandler.NewDefaultServer
orhandler.New
), use theextension.ComplexityLimit
provided bygqlgen
to set a maximum allowed complexity for a query. Example:srv.Use(extension.ComplexityLimit(100))
. - Middleware for Pre-Resolver Check (with
gqlgen
context): Create a middleware that leverages thegqlgen
context (graphql.GetOperationContext(ctx)
) to access the calculated complexity before the resolvers are executed. If the complexity exceeds the limit, return an error immediately. This prevents expensive resolvers from even starting.
Threats Mitigated:
- Denial of Service (DoS) via Query Complexity: (Severity: High) - Prevents attackers from crafting overly complex queries.
- Resource Exhaustion: (Severity: Medium) - Reduces the risk of queries exhausting server resources.
Impact:
- DoS via Query Complexity: Risk significantly reduced.
- Resource Exhaustion: Risk reduced, dependent on accurate complexity values.
Currently Implemented:
- Basic
extension.ComplexityLimit
is implemented inserver/server.go
. - Basic cost directive is implemented.
Missing Implementation:
- Comprehensive complexity values for all fields, especially database interactions.
- Middleware to check complexity before resolver execution using
graphql.GetOperationContext(ctx)
. - Monitoring and alerting for high-complexity queries.
Mitigation Strategy: Introspection Control
Description:
- Environment Check: Use an environment variable (e.g.,
IS_PRODUCTION
). - Conditional Introspection (with
gqlgen
): In your server setup, usegqlgen
'sextension.Introspection{}
:srv := handler.NewDefaultServer(generated.NewExecutableSchema(cfg)) if isProduction { // Your environment check srv.Use(extension.Introspection{}) // Disables introspection }
Threats Mitigated:
- Schema Discovery: (Severity: Medium) - Prevents easy schema discovery.
- Reconnaissance: (Severity: Medium) - Hinders attacker reconnaissance.
Impact:
- Schema Discovery: Risk significantly reduced in production.
- Reconnaissance: Risk reduced.
Currently Implemented:
- Environment variable
APP_ENV
is used. - Introspection is disabled in production using
srv.Use(extension.Introspection{})
inserver/server.go
.
Missing Implementation:
- Authenticated introspection for internal tools (this would require custom middleware, but relies on understanding the
gqlgen
context).
Mitigation Strategy: Custom Scalar Validation
Description:
- Identify Custom Scalars: Review your
schema.graphql
. - Implement
UnmarshalGQL
(withgqlgen
): For each custom scalar, implement theUnmarshalGQL(v interface{}) error
method on the corresponding Go type. This method is generated bygqlgen
, and you must provide the validation logic within it.- Perform thorough type, format, range, and business rule checks.
- Return an error if validation fails.
- Implement
MarshalGQL
(withgqlgen
): Implement theMarshalGQL(w io.Writer)
method (also generated bygqlgen
). - Use Validation Libraries: Leverage libraries like
go-playground/validator
withinUnmarshalGQL
. - Test: Create unit tests for your custom scalar's
UnmarshalGQL
andMarshalGQL
methods.
Threats Mitigated:
- Injection Attacks (via Custom Scalars): (Severity: High)
- Data Corruption: (Severity: Medium)
Impact:
- Injection Attacks: Risk significantly reduced.
- Data Corruption: Risk significantly reduced.
Currently Implemented:
UnmarshalGQL
andMarshalGQL
are implemented for some custom scalars.
Missing Implementation:
- Ensure all custom scalars have complete
UnmarshalGQL
andMarshalGQL
implementations with thorough validation. - Add unit tests for all custom scalar validation.
Mitigation Strategy: Secure Directive Implementation
Description:
- Review Existing Directives: Examine all custom directives and their implementations.
- Validate Directive Arguments (within
gqlgen
's directive handler): Within each directive's implementation (the Go code generated bygqlgen
that handles the directive), treat all arguments as untrusted.- Perform strict type checking.
- Validate format and content.
- Sanitize arguments.
- Avoid Direct Database Access: Directives should not directly interact with databases. Instead:
- Modify the resolver context.
- Influence resolver behavior.
- Let the resolver handle data access.
- Limit Directive Capabilities: Design with the principle of least privilege.
- Test: Create unit tests for your custom directives.
Threats Mitigated:
- Injection Attacks (via Directives): (Severity: High)
- Unauthorized Access: (Severity: Medium)
Impact:
- Injection Attacks: Risk significantly reduced.
- Unauthorized Access: Risk reduced.
Currently Implemented:
- Some basic validation on directive arguments.
Missing Implementation:
- Comprehensive review and audit of all custom directives.
- Refactor to avoid direct database access.
- Add unit tests.
Mitigation Strategy: Secure Error Handling
Description:
- Implement
ErrorPresenter
(withgqlgen
): Usesrv.SetErrorPresenter
in your server setup to define a custom error handling function. This function is provided bygqlgen
. - Sanitize Error Messages: Within the
ErrorPresenter
:- Inspect the error.
- Never include stack traces or internal details in the client-facing message.
- Use generic messages for unexpected errors.
- Provide specific, but sanitized, messages for expected errors.
- Log Detailed Errors: Log full error details internally.
- Error Codes: Consider using error codes.
- Test: Create unit tests that simulate various error conditions.
Threats Mitigated:
- Information Leakage (via Error Messages): (Severity: Medium)
Impact:
- Information Leakage: Risk significantly reduced.
Currently Implemented:
- A basic
ErrorPresenter
is implemented.
Missing Implementation:
- Review and improve the
ErrorPresenter
for comprehensive sanitization. - Ensure comprehensive logging of detailed errors.
- Add unit tests.