HIGH header injectionecho go

Header Injection in Echo Go

How Header Injection Manifests in Echo Go

Header injection vulnerabilities in Echo Go typically arise when user-controlled input is reflected in HTTP response headers without proper validation or encoding. This can lead to HTTP response splitting, session fixation, or cross-site scripting (XSS) through the Set-Cookie header.

In Echo Go applications, header injection commonly occurs in these scenarios:

  • Echo Go handlers that echo back request headers or parameters directly into response headers
  • Middleware that constructs headers from user input without validation
  • Custom authentication logic that builds Set-Cookie headers from user data
  • Proxy headers (X-Forwarded-For, X-Real-IP) being reflected back to clients

Here's a vulnerable Echo Go code pattern:

func vulnerableHandler(c echo.Context) error {
    // User-controlled input from query parameter
    username := c.QueryParam("username")
    
    // Direct header injection without validation
    c.Response().Header().Set("X-User-Name", username)
    
    return c.String(http.StatusOK, "OK")
}

An attacker could exploit this by sending: ?username=normal\r\nSet-Cookie:sessionid=evil, which would inject a new cookie header and potentially hijack sessions.

Another common Echo Go pattern involves cookie manipulation:

func authHandler(c echo.Context) error {
    userID := c.FormValue("user_id")
    
    // Vulnerable: user input directly in Set-Cookie
    c.SetCookie(&http.Cookie{
        Name:  "session_id",
        Value: userID, // Attacker-controlled
        Path:  "/",
    })
    
    return c.String(http.StatusOK, "Authenticated")
}

This allows attackers to inject arbitrary cookie values, potentially leading to session fixation attacks where they set a known session ID for another user.

Echo Go-Specific Detection

Detecting header injection in Echo Go applications requires both static analysis and runtime scanning. middleBrick's black-box scanner can identify these vulnerabilities by testing unauthenticated endpoints for header injection patterns.

For manual detection in Echo Go codebases, look for these patterns:

// Search for these dangerous patterns in your Echo Go handlers:
// 1. Direct header setting from user input
c.Response().Header().Set("Header-Name", userInput)

// 2. Cookie setting from unvalidated input
c.SetCookie(&http.Cookie{Value: userInput})

// 3. Header echoing
c.Response().Header().Set("Reflected-Header", c.Request().Header().Get("User-Header"))

middleBrick scans Echo Go applications by:

  • Testing all endpoints with specially crafted payloads containing CRLF sequences
  • Analyzing response headers for unexpected header injection
  • Checking for reflected headers that could contain XSS payloads
  • Verifying proper header encoding and validation

The scanner provides a security score (A-F) with specific findings like:

Header Injection - High Risk
- Location: /api/user/profile
- Issue: User ID reflected in X-User-ID header without validation
- Severity: High
- Remediation: Validate and encode user input before header injection

For Echo Go applications using middleware, ensure custom middleware doesn't introduce injection points:

func customHeaderMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        // Vulnerable: directly using request header
        forwardedIP := c.Request().Header().Get("X-Forwarded-For")
        c.Response().Header().Set("X-Client-IP", forwardedIP)
        return next(c)
    }
}

This middleware could be exploited if an attacker sends a crafted X-Forwarded-For header containing CRLF sequences.

Echo Go-Specific Remediation

Securing Echo Go applications against header injection requires input validation, proper encoding, and secure header construction patterns. Here are Echo Go-specific remediation techniques:

1. Input Validation and Sanitization:

import "github.com/go-playground/validator/v10"

var validate = validator.New()

func secureHandler(c echo.Context) error {
    username := c.QueryParam("username")
    
    // Validate input - only allow alphanumeric characters
    if err := validate.Var(username, "required,alphanum,max=32"); err != nil {
        return echo.NewHTTPError(http.StatusBadRequest, "Invalid username")
    }
    
    // Safe: validated input in header
    c.Response().Header().Set("X-User-Name", username)
    
    return c.String(http.StatusOK, "OK")
}

2. Safe Cookie Handling:

func secureAuthHandler(c echo.Context) error {
    userID := c.FormValue("user_id")
    
    // Validate and sanitize user ID
    if err := validate.Var(userID, "required,alphanum,max=32"); err != nil {
        return echo.NewHTTPError(http.StatusBadRequest, "Invalid user ID")
    }
    
    // Create secure cookie with proper attributes
    cookie := &http.Cookie{
        Name:     "session_id",
        Value:    generateSecureSessionID(userID), // Server-generated, not user input
        Path:     "/",
        HttpOnly: true,
        Secure:   true, // Only send over HTTPS
        SameSite: http.SameSiteLaxMode,
    }
    
    c.SetCookie(cookie)
    
    return c.String(http.StatusOK, "Authenticated")
}

3. Header Injection Prevention Middleware:

func headerInjectionProtection(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        // Check for dangerous headers in request
        dangerousHeaders := []string{"X-Forwarded-For", "X-Real-IP"}
        for _, header := range dangerousHeaders {
            value := c.Request().Header().Get(header)
            if containsCRLF(value) {
                return echo.NewHTTPError(http.StatusBadRequest, "Invalid header value")
            }
        }
        
        return next(c)
    }
}

func containsCRLF(input string) bool {
    return strings.ContainsAny(input, "\r\n")
}

4. Using Echo Go's Built-in Security Features:

func main() {
    e := echo.New()
    
    // Echo Go's built-in secure middleware
    e.Use(middleware.Secure())
    
    // Custom header injection protection
    e.Use(headerInjectionProtection)
    
    // Rate limiting to prevent abuse
    e.Use(middleware.RateLimiter(
        middleware.NewRateLimiterMemoryStore(10, time.Minute),
    ))
    
    e.GET("/api/user", secureHandler)
    e.POST("/api/auth", secureAuthHandler)
    
    e.Start(":8080")
}

5. Testing Your Remediation:

func TestHeaderInjection(t *testing.T) {
    e := echo.New()
    
    // Test handler with injection attempt
    e.GET("/test", func(c echo.Context) error {
        username := c.QueryParam("username")
        
        // This should reject injection attempts
        if err := validate.Var(username, "required,alphanum,max=32"); err != nil {
            return echo.NewHTTPError(http.StatusBadRequest, "Invalid input")
        }
        
        c.Response().Header().Set("X-Test", username)
        return c.String(http.StatusOK, "OK")
    })
    
    // Test injection attempt
    req := httptest.NewRequest(http.MethodGet, "/test?username=normal%0d%0aSet-Cookie:evil", nil)
    rec := httptest.NewRecorder()
    
    e.ServeHTTP(rec, req)
    
    // Verify header injection was prevented
    if strings.Contains(rec.Header().Get("Set-Cookie"), "evil") {
        t.Error("Header injection vulnerability detected")
    }
}

Frequently Asked Questions

How does middleBrick detect header injection in Echo Go applications?
middleBrick performs black-box scanning by sending specially crafted requests containing CRLF sequences to Echo Go endpoints. The scanner analyzes HTTP responses for unexpected header injection, reflected headers containing user input, and potential XSS vectors. It tests unauthenticated endpoints in 5-15 seconds without requiring credentials or access to source code, providing a security score (A-F) with specific findings and remediation guidance.
What's the difference between header injection and HTTP response splitting?
Header injection is the broader category where user input is reflected in HTTP headers without proper validation. HTTP response splitting is a specific attack that exploits header injection by injecting CRLF sequences to split the HTTP response, allowing attackers to add new headers or create multiple responses. In Echo Go, both vulnerabilities often manifest through similar code patterns where user input is directly used in header construction without validation or encoding.