HIGH dns rebindingchi

Dns Rebinding in Chi

How Dns Rebinding Manifests in Chi

Dns Rebinding attacks in Chi applications typically exploit the framework's HTTP client and DNS resolution behavior. When Chi routes make outbound requests to user-controlled domains, they can fall victim to DNS rebinding where an attacker controls both the initial and rebinding DNS responses.

The most common manifestation occurs in middleware that performs health checks or service discovery. Consider this vulnerable Chi middleware pattern:

func HealthCheckMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Vulnerable: user-controlled domain in config
        healthURL := os.Getenv("HEALTH_CHECK_URL")
        
        resp, err := http.Get(healthURL) // <-- DNS rebinding point
        if err != nil {
            http.Error(w, "Service unavailable", 503)
            return
        }
        defer resp.Body.Close()
        
        next.ServeHTTP(w, r)
    })
}

The attack works by registering a domain that initially resolves to the attacker's IP, then rapidly rebinding it to internal network addresses (192.168.x.x, 10.x.x.x, 127.0.0.1). Chi's default HTTP client follows these DNS changes, potentially exposing internal services.

Another Chi-specific pattern involves route parameters used for external API calls:

router := chi.NewRouter()
router.Get("/api/external/{domain}/{path}", func(w http.ResponseWriter, r *http.Request) {
    vars := chi.RouteContext(r.Context()).URLParams
    domain := vars["domain"]
    path := vars["path"]
    
    // Vulnerable: direct user input in URL construction
    fullURL := fmt.Sprintf("https://%s/%s", domain, path)
    
    resp, err := http.Get(fullURL) // <-- DNS rebinding vulnerability
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }
    defer resp.Body.Close()
    
    w.Write([]byte("External data fetched"))
})

This pattern is particularly dangerous because Chi's routing makes it trivial to extract and use user-controlled domains in outbound requests. The framework's simplicity becomes a liability when combined with DNS rebinding.

Chi-Specific Detection

Detecting DNS rebinding in Chi applications requires both static analysis and runtime scanning. Static analysis should focus on these Chi-specific patterns:

# Scan for vulnerable Chi patterns
rg "chi\.RouteContext|r\.URLParams" --type go
# Look for HTTP clients making requests with user input
rg "http\.Get|http\.Post" --type go
# Find middleware that makes external calls
rg "Middleware.*http\.Get|Middleware.*http\.Post" --type go

For runtime detection, middleBrick's black-box scanning identifies DNS rebinding vulnerabilities by testing Chi endpoints with controlled domains. The scanner monitors for:

  • Internal IP address resolution changes during scan
  • Unexpected responses from private network ranges
  • Time-based DNS resolution patterns indicating rebinding
  • Access to internal services not meant to be exposed

middleBrick specifically tests Chi applications by sending requests to domains that alternate between external and internal IPs, measuring response characteristics to confirm DNS rebinding exploitation.

Additional detection can be implemented in Chi middleware:

func DNSSecurityMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Block requests with internal IP patterns in URLs
        if strings.Contains(r.URL.String(), "192.168.") ||
           strings.Contains(r.URL.String(), "10.") ||
           strings.Contains(r.URL.String(), "127.") {
            http.Error(w, "Invalid request", 400)
            return
        }
        
        // Rate limit requests to the same domain
        domain := r.URL.Hostname()
        // Implement rate limiting logic here
        
        next.ServeHTTP(w, r)
    })
}

Chi-Specific Remediation

Remediating DNS rebinding in Chi requires a defense-in-depth approach using the framework's middleware capabilities. The primary defense is input validation and allowlisting:

var allowedDomains = map[string]bool{
    "api.example.com": true,
    "service.example.org": true,
}

func SecureExternalCallMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Extract domain from route or query
        domain := chi.RouteContext(r.Context()).URLParams["domain"]
        
        // Validate against allowlist
        if !allowedDomains[domain] {
            http.Error(w, "Invalid domain", 400)
            return
        }
        
        // Resolve DNS once and cache (prevents rebinding)
        ips, err := net.LookupIP(domain)
        if err != nil || len(ips) == 0 {
            http.Error(w, "Domain resolution failed", 502)
            return
        }
        
        // Store resolved IP in context for single use
        ctx := context.WithValue(r.Context(), "resolvedIP", ips[0])
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

For HTTP client configuration, use timeouts and custom DNS resolvers:

func NewSecureHTTPClient() *http.Client {
    return &http.Client{
        Timeout: 10 * time.Second,
        Transport: &http.Transport{
            DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
                // Block internal network connections
                host, _, err := net.SplitHostPort(addr)
                if err != nil {
                    return nil, err
                }
                
                ip := net.ParseIP(host)
                if ip != nil {
                    if ip.IsPrivate() || ip.IsLoopback() {
                        return nil, errors.New("internal IP blocked")
                    }
                }
                
                return net.DialTimeout(network, addr, 10*time.Second)
            },
        },
    }
}

Implement middleware for Chi routes that accept external domains:

func ValidateExternalDomain(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        vars := chi.RouteContext(r.Context()).URLParams
        domain := vars["domain"]
        
        // Basic validation - allow only specific TLDs
        if !strings.HasSuffix(domain, ".com") && !strings.HasSuffix(domain, ".org") {
            http.Error(w, "Invalid domain format", 400)
            return
        }
        
        // Check for internal IP patterns
        if strings.Contains(domain, "192.168") || strings.Contains(domain, "10.") {
            http.Error(w, "Internal network access denied", 403)
            return
        }
        
        next.ServeHTTP(w, r)
    })
}

// Usage in Chi router
router := chi.NewRouter()
router.Use(ValidateExternalDomain)
router.Get("/api/external/{domain}/{path}", externalHandler)

Frequently Asked Questions

How does DNS rebinding differ from SSRF in Chi applications?
DNS rebinding is a specific attack where DNS records change during a session, allowing access to internal services. SSRF (Server-Side Request Forgery) is broader, encompassing any unauthorized server-initiated requests. In Chi, DNS rebinding specifically exploits the framework's HTTP client behavior when resolving user-controlled domains, while SSRF includes other attack vectors like XHR requests, gRPC calls, or database connections. Both require input validation, but DNS rebinding needs additional defenses like DNS caching and IP allowlisting.
Can middleBrick detect DNS rebinding in Chi applications?
Yes, middleBrick's black-box scanning specifically tests for DNS rebinding vulnerabilities in Chi applications. The scanner sends requests to domains that alternate between external and internal IP addresses, monitoring for successful internal network access. It tests all 12 security categories including Authentication, BOLA/IDOR, and Input Validation. For Chi applications, middleBrick identifies vulnerable middleware patterns, route handlers that make external requests, and configuration files that allow user-controlled domains. The scanner provides specific remediation guidance for Chi's Go-based architecture.