Skip to content

[P7.0.2] Webhook URL SSRF: block internal/metadata/private hosts (M2) #656

Description

@frankbria

Problem

Outbound-webhook SSRF: the webhook URL validator checks the scheme (blocks file:///ftp://) but performs no host validation. An authenticated user can set the webhook URL — and the /notifications/test endpoint fires it immediately — to http://169.254.169.254/... (cloud metadata / IMDS), http://localhost:8000/..., or any internal RFC1918 address. The test endpoint returns the HTTP status code to the caller, giving a blind-to-semi-blind SSRF primitive against internal services and cloud metadata. Especially relevant on cloud VPS deployments with IMDSv1.

Evidence

  • codeframe/ui/routers/settings_v2.py:447-480_validate_webhook_url validates scheme only, no host check
  • codeframe/notifications/webhook.py:235-291send_event POSTs to the URL (5s timeout); test endpoint surfaces status code

Fix

  • After parsing, resolve the host and reject loopback, link-local (169.254.0.0/16), and RFC1918/private ranges (and IPv6 equivalents) unless explicitly opted in.
  • Consider pinning the resolved IP through the request to mitigate DNS-rebinding TOCTOU.

Acceptance criteria

  • Webhook URLs pointing at private/loopback/link-local/metadata hosts are rejected by both save and test endpoints.
  • Test covers the metadata IP and localhost cases.

Source: release-readiness audit 2026-06-13 (security agent, finding M2).

Metadata

Metadata

Assignees

No one assigned

    Labels

    FutureDeferred - beyond v1/v2 scope, consider for future versionsphase-7Phase 7: Hosted / multi-tenant readinesssecurity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions