Rules / Go
SHIELD-GO-010
Server-Side Request Forgery via http.Get with user input
What it detects
Fetching user-controlled URLs with http.Get or http.Post may allow SSRF.
How to fix
Validate URLs against an allowlist before making outbound HTTP requests.
Vulnerable — Shield flags thisfetch.go
package proxy
import (
"io"
"net/http"
)
func FetchHandler(w http.ResponseWriter, r *http.Request) {
// Attacker can target http://169.254.169.254/ or internal services
resp, err := http.Get(r.URL.Query().Get("url"))
if err != nil {
http.Error(w, "fetch failed", http.StatusBadGateway)
return
}
defer resp.Body.Close()
io.Copy(w, resp.Body)
}
Fixed — scans cleanfetch.go
package proxy
import (
"io"
"net/http"
)
var allowedServices = map[string]string{
"status": "https://status.example.com/api/summary",
"weather": "https://weather.example.com/api/today",
}
func FetchHandler(w http.ResponseWriter, r *http.Request) {
target, ok := allowedServices[r.URL.Query().Get("service")]
if !ok {
http.Error(w, "unknown service", http.StatusBadRequest)
return
}
resp, err := http.Get(target)
if err != nil {
http.Error(w, "fetch failed", http.StatusBadGateway)
return
}
defer resp.Body.Close()
io.Copy(w, resp.Body)
}
Both snippets are verified against the shipped scanner: the vulnerable one triggers SHIELD-GO-010, the fixed one does not.