Fix SSRF (Server Side Request Forgery) in Echo
SSRF in Go's Echo framework occurs when an application accepts a user-supplied URL and makes a server-side request without validation. This allows attackers to pivot into internal networks, access cloud metadata services (like 169.254.169.254), or bypass firewalls. Simply checking the string for 'localhost' is insufficient; you must validate the resolved IP address to prevent DNS rebinding and CIDR-based bypasses.
The Vulnerable Pattern
e.GET("/fetch", func(c echo.Context) error {
target := c.QueryParam("url")
// CRITICAL: Directly fetching user-controlled URL
resp, err := http.Get(target)
if err != nil {
return c.String(http.StatusInternalServerError, "Error")
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
return c.String(http.StatusOK, string(body))
})
The Secure Implementation
To properly mitigate SSRF, you must implement a custom http.Client with a Control function in the DialContext. This allows the server to validate the destination IP address AFTER DNS resolution but BEFORE the connection is established. This prevents 'DNS Rebinding' attacks where an attacker changes the DNS record to point to an internal IP after the initial validation. The secure implementation checks for loopback, link-local, and private CIDR blocks (RFC 1918) at the socket level.
var secureClient = &http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: 5 * time.Second, Control: func(network, address string, c syscall.RawConn) error { host, _, _ := net.SplitHostPort(address) ips, _ := net.LookupIP(host) for _, ip := range ips { if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsPrivate() { return fmt.Errorf("blocked internal IP: %s", ip) } } return nil }, }).DialContext, }, }
e.GET(“/fetch”, func(c echo.Context) error { target := c.QueryParam(“url”) parsedUrl, err := url.Parse(target) if err != nil || (parsedUrl.Scheme != “http” && parsedUrl.Scheme != “https”) { return c.String(http.StatusBadRequest, “Invalid URL”) } resp, err := secureClient.Get(target) if err != nil { return c.String(http.StatusForbidden, “Access Denied”) } defer resp.Body.Close() return c.NoContent(http.StatusOK) })
Your Echo API
might be exposed to SSRF (Server Side Request Forgery)
74% of Echo apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
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.