Failure scenario
- Enable Slack notifications with a configured default webhook.
- Call
POST /api/slack/send with channel set to any attacker-controlled https:// URL, or configure a public-looking webhook endpoint that redirects to a blocked destination.
- Submit any text.
resolve_url() treats every request-supplied HTTPS string as a webhook URL instead of requiring a configured channel. send() then posts to it with normal aiohttp redirect and DNS behavior. This lets the API endpoint act as a POST primitive to arbitrary HTTPS services; a public endpoint can redirect the request to a loopback, private-network, or metadata address without any per-hop validation.
Sites
src/notifications/slack.py:109-114 accepts an arbitrary request-supplied HTTPS URL as a destination.
src/notifications/slack.py:132-160 sends without request-time destination, DNS, or redirect validation.
src/web/api/integrations.py:484-508 passes the request's channel value directly to that resolver.
Expected result
Resolve only configured channel names for API calls, and deliver through the repository's SSRF-safe transport with redirect-hop validation and DNS pinning. If direct webhook URLs are intentionally supported elsewhere, gate them behind an explicit privileged configuration surface rather than overloading channel.
Failure scenario
POST /api/slack/sendwithchannelset to any attacker-controlledhttps://URL, or configure a public-looking webhook endpoint that redirects to a blocked destination.resolve_url()treats every request-supplied HTTPS string as a webhook URL instead of requiring a configured channel.send()then posts to it with normalaiohttpredirect and DNS behavior. This lets the API endpoint act as a POST primitive to arbitrary HTTPS services; a public endpoint can redirect the request to a loopback, private-network, or metadata address without any per-hop validation.Sites
src/notifications/slack.py:109-114accepts an arbitrary request-supplied HTTPS URL as a destination.src/notifications/slack.py:132-160sends without request-time destination, DNS, or redirect validation.src/web/api/integrations.py:484-508passes the request'schannelvalue directly to that resolver.Expected result
Resolve only configured channel names for API calls, and deliver through the repository's SSRF-safe transport with redirect-hop validation and DNS pinning. If direct webhook URLs are intentionally supported elsewhere, gate them behind an explicit privileged configuration surface rather than overloading
channel.