Webhook URL validation must resolve DNS — hostnames pointing at private space are allowed #51
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot#51
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
validate_webhook_url(app/services/webhook_security.py:18-45) blocks literalprivate IPs and a static hostname blocklist but never resolves hostnames, so a
DNS name resolving to private/loopback/link-local space passes validation at
both store time (app/api/channels.py:52-57) and send time
(app/services/notifiers/webhook.py). Fix: resolve the host during validation
and again at send; reject when any resolved address is
private/loopback/link-local/reserved; pin the connection to the validated
address (custom transport) so the checked IP is the connected IP. Keep the
existing literal/blocklist checks as the fast path.
Acceptance criteria:
Filed from the 2026-07-17 codebase audit (
docs/.internal/report-2026-07-17.md), finding F-12.Fixed in #93 (merged to
main).validate_webhook_urlnow resolves all A/AAAA records (viasocket.getaddrinfo, keeping the sync signature so the store-time call site is unchanged) and rejects any host whose resolved addresses include private/loopback/link-local/reserved/non-global space (IPv4-mapped IPv6 unwrapped first; unresolvable hosts rejected). At send time the generic webhook path pins the connection to the validated IP while preserving theHostheader and TLS SNI, closing the DNS-rebinding (resolve-then-connect) gap. Tests cover private-resolution rejection, the still-valid public host, unresolvable hosts, and that the send targets the validated IP.