Skip to content

fix(adapters): guard attachment downloads across slack, discord, telegram, and whatsapp - #865

Open
bensabic wants to merge 2 commits into
mainfrom
ben/guarded-attachment-downloads
Open

fix(adapters): guard attachment downloads across slack, discord, telegram, and whatsapp#865
bensabic wants to merge 2 commits into
mainfrom
ben/guarded-attachment-downloads

Conversation

@bensabic

@bensabic bensabic commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Follows up on #850, #856, and #859 by adopting the shared guarded downloader (downloadAttachment in @chat-adapter/shared) in the remaining adapters that fetch attachment bytes from event-supplied URLs.

  • Slack, Discord, and WhatsApp attachment downloads now refuse private and internal addresses (as URL literals, through DNS resolution, and after redirects), cap responses at 25 MB, and time out after 30 seconds.
  • Slack sends the bot token only on hops to trusted Slack origins, so a redirect can never carry it to another host, and keeps the HTML-login-page detection. A protected createFileTransport() override routes downloads through a proxy.
  • WhatsApp keeps its access token on Meta's media hosts, and the configured Graph origin via the hosts allowlist; downloadMedia() accepts a custom transport.
  • Telegram keeps downloads on the Web Fetch API because a downstream Cloudflare Workers consumer depends on portability (fix(telegram): return portable file data #828), enforcing the same 25 MB cap and 30-second timeout with web streams.
  • downloadAttachment now resolves headers per hop (function form decides what each redirect target receives), forwards the resolved headers to custom transports, and accepts an onResponse hook that can reject a final response before its body is read.
  • Adds "Inbound attachments" docs sections for all four adapters.

…gram, and whatsapp

- route Slack, Discord, and WhatsApp attachment downloads through the shared guarded downloader (SSRF blocklist, DNS pinning, redirect revalidation, 25 MB cap, 30 second timeout)
- send the Slack bot token only on hops to trusted Slack origins and add a createFileTransport() override for proxies
- keep the WhatsApp access token on Meta media hosts and the configured Graph origin; downloadMedia() accepts a custom transport
- cap and time out Telegram file downloads with the Web Fetch API so runtimes like Cloudflare Workers keep working
- resolve downloadAttachment headers per hop, forward them to custom transports, and add an onResponse hook
- document inbound attachment policies for all four adapters
@bensabic
bensabic requested a review from a team as a code owner August 25, 2026 12:06
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chat Ready Ready Preview, v0 Aug 26, 2026 3:02am
chat-sdk-nextjs-chat Ready Ready Preview, v0 Aug 26, 2026 3:02am

Comment thread packages/adapter-whatsapp/src/index.ts Outdated
@gr2m gr2m removed their assignment Aug 25, 2026
…token

- check each redirect target against the exact-origin and Meta media host policy before attaching the authorization header
- refuse off-policy hops such as subdomains of the Graph origin or the same host on another port
- add regression tests for both cases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants