Ssrf in Gin with Basic Auth
Ssrf in Gin with Basic Auth — how this specific combination creates or exposes the vulnerability
Server-Side Request Forgery (SSRF) in Gin when Basic Authentication is used can arise when an endpoint that accepts a user-supplied URL performs an outbound HTTP request on the server. Even when Basic Auth credentials are required to reach a target, an attacker can supply a malicious internal address or a crafted external URL that causes the server to interact with unintended services. For example, an endpoint that proxies requests to a protected resource may forward the credentials to an internal metadata service, bypassing network segregation.
Consider a Gin handler that reads a URL from a query parameter and uses http.Get without validation. If that handler adds Basic Auth headers derived from user input, the server may be tricked into authenticating to internal endpoints that are normally protected by network-level access controls. Attack patterns such as probing internal IPs (e.g., http://169.254.169.254 for cloud metadata) or internal Kubernetes services become feasible. The presence of Basic Auth may give a false sense of security, while the SSRF vector remains because the attacker controls both the target URL and the credentials used.
Insecure coding practices amplify the risk. If the server does not enforce a strict allowlist of acceptable hosts or fails to sanitize the port and scheme, an attacker can leverage Basic Auth to reach internal TCP services that only require username/password protection. This can lead to data exposure, internal reconnaissance, or further pivoting. MiddleBrick’s unauthenticated black-box scanning detects such endpoint behaviors by analyzing how the API handles user-supplied URLs and whether outbound requests are constrained.
Real-world examples align with the OWASP API Top 10 A05:2023 — Security Misconfiguration and A01:2023 — Broken Object Level Authorization in network context. Instances of SSRF in Gin with Basic Auth should be assessed against CWE-918. MiddleBrick’s checks include input validation and SSRF-specific tests that flag endpoints that forward requests without host or scheme validation.
Basic Auth-Specific Remediation in Gin — concrete code fixes
To mitigate SSRF in Gin when using Basic Authentication, enforce strict input validation and avoid using user-controlled data to construct outbound request targets. Prefer allowlisting permitted hosts and ports, and do not forward credentials to user-supplied URLs. The following patterns demonstrate secure approaches.
Example 1: Safe proxy with allowlist and no credential forwarding
package main
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
var allowedHosts = map[string]bool{
"api.example.com": true,
"data.service.com": true,
}
func safeProxy(c *gin.Context) {
target := c.Query("url")
if target == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "url parameter is required"})
return
}
// Basic validation: must use HTTPS and host must be in allowlist
if !strings.HasPrefix(target, "https://") {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "only HTTPS URLs are allowed"})
return
}
// Parse host and enforce allowlist
// In production, use a proper URL parser and stricter checks
// This is simplified for illustration
if !allowedHosts["api.example.com"] { // Replace with dynamic host extraction and allowlist check
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "host not allowed"})
return
}
// Create request without inheriting user-supplied credentials
req, err := http.NewRequest("GET", target, nil)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid URL"})
return
}
req.Header.Set("User-Agent", "middleBrick-safe-client")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadGateway, gin.H{"error": "request failed"})
return
}
defer resp.Body.Close()
// Forward response status and selected headers as needed
c.Status(resp.StatusCode)
}
Example 2: Explicit Basic Auth for a fixed backend (no user input in credentials)
package main
import (
"net/http"
"net/url"
"github.com/gin-gonic/gin"
)
func fixedBackendProxy(c *gin.Context) {
// The target is fixed and validated, not user-controlled
const fixedURL = "https://api.example.com/health"
req, err := http.NewRequest("GET", fixedURL, nil)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid configuration"})
return
}
// Set Basic Auth for the fixed backend only
req.SetBasicAuth("serviceaccount", "SuperSecretPassword") // Use secrets management in practice
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadGateway, gin.H{"error": "backend unreachable"})
return
}
defer resp.Body.Close()
c.Status(resp.StatusCode)
}
General hardening measures
- Do not construct outbound URLs from user input without strict validation and allowlisting.
- Do not forward Basic Auth credentials (or any credentials) to user-supplied hosts.
- Use a strict URL parser to validate scheme, host, and port, and reject unexpected patterns (e.g., non-HTTPS, non-standard ports).
- Apply network-level protections and network segmentation to limit exposure of internal services.
- Monitor outbound traffic and implement defense in depth with WAF or gateway policies where appropriate.
MiddleBrick’s scans include input validation and SSRF checks that highlight endpoints where user-controlled URLs reach backend services, helping you identify risky patterns before they are exploited.
Related CWEs: ssrf
| CWE ID | Name | Severity |
|---|---|---|
| CWE-918 | Server-Side Request Forgery (SSRF) | CRITICAL |
| CWE-441 | Unintended Proxy or Intermediary (Confused Deputy) | HIGH |