Say how to allow a refused private target address (closes #398)
check / check (push) Failing after 4m3s
check / check (push) Failing after 4m3s
Adding or editing an http or slack target whose address is private or reserved was refused with no hint that the refusal is deliberate or that it can be lifted. The refusal now adds that such addresses are refused by default and that the server's ALLOWED_EGRESS_CIDRS setting allows named networks, naming the README section "Allowing egress to your own network". Metadata refusals do not get it: link-local and the other unconditional metadata addresses cannot be opened, and Azure's WireServer, which listing does open, serves VM credentials. The delivery package refuses WireServer with its own error and exports the private-or-reserved one as ErrBlockedIP, so the handler can tell them apart. Model: opus-5-5
This commit is contained in:
@@ -17,6 +17,10 @@ const (
|
||||
// dnsResolutionTimeout is the maximum time to wait for
|
||||
// DNS resolution during SSRF validation.
|
||||
dnsResolutionTimeout = 5 * time.Second
|
||||
|
||||
// azureWireServer is Azure's WireServer, a public address that
|
||||
// serves VM credentials.
|
||||
azureWireServer = "168.63.129.16"
|
||||
)
|
||||
|
||||
// Sentinel errors for SSRF validation.
|
||||
@@ -25,8 +29,14 @@ var (
|
||||
errNoIPs = errors.New(
|
||||
"hostname resolved to no IP addresses",
|
||||
)
|
||||
errBlockedIP = errors.New(
|
||||
"blocked private, reserved or cloud metadata address",
|
||||
// ErrBlockedIP reports a private or reserved address the
|
||||
// default blocklist refuses, one that ALLOWED_EGRESS_CIDRS
|
||||
// can open.
|
||||
ErrBlockedIP = errors.New(
|
||||
"blocked private or reserved address",
|
||||
)
|
||||
errBlockedWireServer = errors.New(
|
||||
"blocked cloud metadata address",
|
||||
)
|
||||
errBlockedMetadata = errors.New(
|
||||
"blocked link-local or cloud instance metadata " +
|
||||
@@ -123,8 +133,7 @@ func init() {
|
||||
"::1/128",
|
||||
"fc00::/7",
|
||||
"fe80::/10",
|
||||
// Azure WireServer, a public address that serves VM credentials.
|
||||
"168.63.129.16/32",
|
||||
azureWireServer + "/32",
|
||||
})
|
||||
|
||||
// Every entry is named. The set must not grow or shrink
|
||||
@@ -338,9 +347,17 @@ func (g *Guard) checkIP(ip net.IP) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// WireServer is on the default blocklist but is a public
|
||||
// address, so its refusal does not call it private or reserved.
|
||||
if ip.Equal(net.ParseIP(azureWireServer)) {
|
||||
return fmt.Errorf(
|
||||
"target IP %s: %w", ip, errBlockedWireServer,
|
||||
)
|
||||
}
|
||||
|
||||
if isBlockedIP(ip) {
|
||||
return fmt.Errorf(
|
||||
"target IP %s: %w", ip, errBlockedIP,
|
||||
"target IP %s: %w", ip, ErrBlockedIP,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user