Files
webhooker/internal/config/config.go
sneak 71a3c3cf75
All checks were successful
check / check (push) Successful in 5m25s
Add an egress CIDR allowlist to the SSRF guard (closes #204)
The SSRF blocklist had no escape hatch, so the thing webhooker is
mostly for — taking a public webhook and forwarding it to something
on your own network — could not be configured at all. Every private
address, Docker sibling and loopback service was permanently
unreachable as a delivery destination.

ALLOWED_EGRESS_CIDRS (default empty) names blocks that delivery
targets may reach despite the default blocklist. It is an allowlist
and only ever adds destinations: there is no boolean, and no value
disables SSRF protection wholesale. Empty, the guard behaves exactly
as before.

Link-local (169.254.0.0/16, fe80::/10) is refused before the
allowlist is consulted, so no supplied CIDR can open it — not the
exact address, not a supernet, not 0.0.0.0/0. Reaching cloud
instance metadata is credential theft rather than delivery to an
internal service.

The policy now lives in one function, Guard.checkIP, which both
target-creation validation and the delivery dialer call. The two
paths previously decided separately, which is how they came to
disagree about a destination. The guard is built once from config
and injected via fx into both the handlers and the delivery engine,
so there is a single instance and a single answer.

A set-but-unparseable value aborts startup naming the variable,
reusing the existing envPrefixList parser. A non-empty list is
logged at startup with the blocks spelled out, not counted, so the
hole is visible in the log of any deployment that has one.

Tests: an allowlisted loopback CIDR both validates and delivers to a
live server (and the same URL still fails without the allowlist); a
private address outside the listed block stays refused on both
paths; metadata stays refused under six different covering CIDRs;
public addresses are unaffected either way; and config coverage for
parsing, startup abort, and the warning's contents.
2026-08-20 04:13:09 +00:00

18 KiB