Denial Of Service in Echo Go
Echo Go-Specific Remediation
Securing Echo Go applications against DoS attacks requires configuring the framework's built-in protection mechanisms. Echo Go provides several configuration options that, when properly set, prevent the most common DoS vectors.
Connection timeouts are the first line of defense. Echo Go's ReadTimeout and WriteTimeout prevent slowloris attacks by terminating connections that take too long to complete:
func main() {
e := echo.New()
// Configure timeouts to prevent slowloris
e.Server.ReadTimeout = 10 * time.Second
e.Server.WriteTimeout = 10 * time.Second
e.Server.IdleTimeout = 60 * time.Second
// Body size limits prevent memory exhaustion
e.MaxBodySize = 10 * 1024 * 1024 // 10MB limit
e.MaxHeaderSize = 1 * 1024 * 1024 // 1MB limit
// Rate limiting middleware
e.Use(middleware.RateLimiterWithConfig(middleware.RateLimiterConfig{
Store: middleware.NewRateLimitMemoryStore(100),
Config: middleware.RateLimitConfig{
Limit: 100,
Identifier: func(ctx echo.Context) string {
return ctx.RealIP()
},
},
}))
e.GET("/api/data", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
})
e.Start(":8080")
}
Echo Go's middleware ecosystem provides additional DoS protection. The built-in rate limiting middleware prevents request flooding by tracking request counts per client IP:
// Custom rate limiting with Echo middleware
func rateLimitMiddleware(limit int) echo.MiddlewareFunc {
return middleware.RateLimiterWithConfig(middleware.RateLimiterConfig{
Store: middleware.NewRateLimitMemoryStore(limit),
Config: middleware.RateLimitConfig{
Limit: limit,
Identifier: func(ctx echo.Context) string {
return ctx.RealIP()
},
Skip: func(ctx echo.Context) error {
// Skip health checks
if ctx.Path() == "/health" {
return middleware.Skip
}
return nil
},
},
})
}
For CPU-intensive operations, Echo Go applications should implement request timeouts at the handler level. This prevents single requests from monopolizing server resources:
func secureHandler(c echo.Context) error {
// Set context timeout for this specific operation
ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second)
defer cancel()
// Wrap expensive operation with timeout
result, err := processWithTimeout(ctx)
if err != nil {
return c.JSON(http.StatusGatewayTimeout, map[string]string{"error": "operation timed out"})
}
return c.JSON(http.StatusOK, result)
}
func processWithTimeout(ctx context.Context) (interface{}, error) {
// Simulate expensive operation with timeout
select {
case <-time.After(3 * time.Second):
return map[string]string{"status": "processed"}, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
Echo Go's context-based cancellation also helps prevent DoS by allowing operations to be cancelled when clients disconnect:
func cancelableHandler(c echo.Context) error {
// Automatically cancelled if client disconnects
ctx := c.Request().Context()
// Process with context cancellation
result, err := processWithCancellation(ctx)
if err != nil {
if errors.Is(err, context.Canceled) {
return c.JSON(http.StatusServiceUnavailable, map[string]string{"error": "connection lost"})
}
return err
}
return c.JSON(http.StatusOK, result)
}
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |