Skip to content

Outbound webhooks can follow redirects to blocked network destinations #307

Description

@Calmingstorm

Failure scenario

  1. Register a webhook URL whose initial public address passes is_url_blocked().
  2. Have that endpoint answer with a 307 or 308 redirect to a loopback, private-network, or cloud-metadata destination.
  3. Dispatch any subscribed event.

Registration validates only the original URL. Delivery uses aiohttp's redirect-following default, so the redirected destination is never checked and the POST (including its event body and signature header) is resent to an address the registration guard explicitly intends to block. A hostname that changes DNS answers between registration and delivery creates the same bypass because no resolved address is pinned or revalidated.

Sites

  • src/notifications/outbound_webhooks.py:223-247 validates only the registration-time URL.
  • src/notifications/outbound_webhooks.py:297-313 does the same only when an updated URL is stored.
  • src/notifications/outbound_webhooks.py:368-379 posts through the default redirect/DNS behavior without per-hop destination validation.

src/tools/safe_fetch.py:202-279 already contains the repository's manual per-hop validation and DNS-pinning transport pattern; the webhook path bypasses it.

Expected result

Use an SSRF-safe delivery transport that disables automatic redirects, validates and pins every hop at request time, and strips sensitive headers on any permitted cross-origin redirect.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions