GuardAPI Logo
GuardAPI

Fix SSRF (Server Side Request Forgery) in Chi

SSRF (Server-Side Request Forgery) in Go/Chi applications allows attackers to abuse the server's network identity to scan internal ports, hit cloud metadata services (169.254.169.254), or bypass firewalls. If your Chi handler fetches a URL provided by a user without strict validation, your backend is a proxy for the attacker. To mitigate this, you must implement a multi-layered defense: protocol enforcement, domain allowlisting, and IP-level validation to block private address ranges.

The Vulnerable Pattern

func (s *Server) VulnerableHandler(w http.ResponseWriter, r *http.Request) {
    targetURL := r.URL.Query().Get("url")
    // CRITICAL: Blindly fetching user-provided URL
    resp, err := http.Get(targetURL)
    if err != nil {
        http.Error(w, "Failed to fetch", 500)
        return
    }
    defer resp.Body.Close()
    io.Copy(w, resp.Body)
}

The Secure Implementation

The secure implementation introduces three critical checks. First, it enforces the 'http' and 'https' schemes to prevent protocol smuggling (e.g., file:// or gopher://). Second, it uses a strict domain allowlist to ensure the server only communicates with known entities. Finally, it performs a DNS lookup and inspects the resulting IP addresses. By checking 'ip.IsPrivate()' and 'ip.IsLoopback()', the code prevents the server from connecting to its own localhost or internal network segments (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). For production-grade security, consider using a custom 'http.Transport' with a 'DialContext' that validates IPs after DNS resolution to prevent DNS rebinding attacks.

func isSafe(urlStr string) (string, error) {
    u, err := url.Parse(urlStr)
    if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
        return "", errors.New("invalid scheme")
    }
    allowedDomains := map[string]bool{"api.trusted.com": true, "images.trusted.com": true}
    if !allowedDomains[u.Hostname()] {
        return "", errors.New("domain not allowed")
    }
    addrs, err := net.LookupHost(u.Hostname())
    if err != nil {
        return "", err
    }
    for _, addr := range addrs {
        ip := net.ParseIP(addr)
        if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsUnspecified() {
            return "", errors.New("internal IP detected")
        }
    }
    return u.String(), nil
}

func (s *Server) SecureHandler(w http.ResponseWriter, r *http.Request) { target := r.URL.Query().Get(“url”) validatedURL, err := isSafe(target) if err != nil { http.Error(w, “Forbidden: “+err.Error(), 403) return } client := &http.Client{Timeout: 5 * time.Second} resp, err := client.Get(validatedURL) if err != nil { http.Error(w, “Request failed”, 502) return } defer resp.Body.Close() io.Copy(w, resp.Body) }

System Alert • ID: 7844
Target: Chi API
Potential Vulnerability

Your Chi API might be exposed to SSRF (Server Side Request Forgery)

74% of Chi apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.