Skip to content

Latest commit

 

History

History
137 lines (106 loc) · 7.14 KB

File metadata and controls

137 lines (106 loc) · 7.14 KB

Mitigation Strategies Analysis for 99designs/gqlgen

Description:

  1. Assign Complexity Values (with gqlgen): Use gqlgen's support for complexity functions. Within your resolvers, access the graphql.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.
  2. Set a Complexity Limit (with gqlgen): In your server configuration (using handler.NewDefaultServer or handler.New), use the extension.ComplexityLimit provided by gqlgen to set a maximum allowed complexity for a query. Example: srv.Use(extension.ComplexityLimit(100)).
  3. Middleware for Pre-Resolver Check (with gqlgen context): Create a middleware that leverages the gqlgen 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 in server/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:

  1. Environment Check: Use an environment variable (e.g., IS_PRODUCTION).
  2. Conditional Introspection (with gqlgen): In your server setup, use gqlgen's extension.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{}) in server/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:

  1. Identify Custom Scalars: Review your schema.graphql.
  2. Implement UnmarshalGQL (with gqlgen): For each custom scalar, implement the UnmarshalGQL(v interface{}) error method on the corresponding Go type. This method is generated by gqlgen, and you must provide the validation logic within it.
    • Perform thorough type, format, range, and business rule checks.
    • Return an error if validation fails.
  3. Implement MarshalGQL (with gqlgen): Implement the MarshalGQL(w io.Writer) method (also generated by gqlgen).
  4. Use Validation Libraries: Leverage libraries like go-playground/validator within UnmarshalGQL.
  5. Test: Create unit tests for your custom scalar's UnmarshalGQL and MarshalGQL 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 and MarshalGQL are implemented for some custom scalars.

Missing Implementation:

  • Ensure all custom scalars have complete UnmarshalGQL and MarshalGQL implementations with thorough validation.
  • Add unit tests for all custom scalar validation.

Mitigation Strategy: Secure Directive Implementation

Description:

  1. Review Existing Directives: Examine all custom directives and their implementations.
  2. Validate Directive Arguments (within gqlgen's directive handler): Within each directive's implementation (the Go code generated by gqlgen that handles the directive), treat all arguments as untrusted.
    • Perform strict type checking.
    • Validate format and content.
    • Sanitize arguments.
  3. 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.
  4. Limit Directive Capabilities: Design with the principle of least privilege.
  5. 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:

  1. Implement ErrorPresenter (with gqlgen): Use srv.SetErrorPresenter in your server setup to define a custom error handling function. This function is provided by gqlgen.
  2. 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.
  3. Log Detailed Errors: Log full error details internally.
  4. Error Codes: Consider using error codes.
  5. 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.