You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(security): block SSRF to internal/metadata hosts in webhook URLs (#656) (#706)
* fix(security): block SSRF to internal/metadata hosts in webhook URLs (#656)
Webhook URL validation checked the scheme only. An authenticated user could
point the outbound webhook at http://169.254.169.254 (cloud IMDS),
http://localhost, or any RFC1918 address; the /notifications/test endpoint
fires it immediately and returns the HTTP status — a blind-to-semi-blind SSRF
primitive.
- _validate_webhook_url now resolves the host and rejects loopback,
link-local, RFC1918/private, reserved, multicast and unspecified addresses
(IPv4, IPv6, and IPv4-mapped IPv6). Covers both save (PUT) and test (POST).
- Opt-out via CODEFRAME_ALLOW_PRIVATE_WEBHOOKS=1 for self-hosted operators
with legitimate internal webhook targets.
- send_event no longer follows redirects (allow_redirects=False) — closes the
public-target-302-to-metadata bypass.
- Host resolution runs off the event loop (run_in_threadpool) so a slow
resolver can't stall request handling.
Known limitation: resolve-and-check at save/test time, not a request-time
pinned connector, so DNS rebinding (public at save, private at fire) is out of
scope; redirect-blocking mitigates the most practical variant.
* test(security): harden #656 SSRF tests; reword docstring
Address advisory review feedback:
- Add IPv4-mapped IPv6 metadata test (::ffff:169.254.169.254) — the trickiest
case, previously only exercised in the demo.
- Make the localhost test hermetic by mocking socket.getaddrinfo instead of
depending on CI-image resolution of 'localhost'.
- test_accepts_http uses a global IP literal (8.8.8.8) — no live DNS; TEST-NET
ranges count as private under ipaddress so they can't serve as 'public'.
- Opt-in test also covers an RFC1918 host, not just loopback.
- Reword 'ponytail:' docstring note to 'Known limitation:'.
* docs: document CODEFRAME_ALLOW_PRIVATE_WEBHOOKS env var (#656)
0 commit comments