GuardAPI Logo
GuardAPI

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) })

System Alert • ID: 9583
Target: Echo API
Potential Vulnerability

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.

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.