#6916: fix(slack): add timeout to file download to prevent DoS (CWE-400)
channel: slack
## Summary
Add `AbortSignal.timeout()` to both fetch calls in `fetchWithSlackAuth()` to prevent indefinite hangs when Slack CDN is slow or unresponsive.
- **Initial auth request**: 30s timeout
- **Redirect follow**: 30s timeout
- Optional `timeoutMs` parameter for configurability while maintaining backward compatibility
## Security
- **CWE**: [CWE-400](https://cwe.mitre.org/data/definitions/400.html) - Uncontrolled Resource Consumption
- **CVSS**: 7.5 (High) - Network-based DoS vector
- **Impact**: Without timeouts, a slow/malicious Slack CDN can hang the gateway indefinitely, exhausting connections and blocking threads
## Changes
| File | Change |
|------|--------|
| `src/slack/monitor/media.ts` | Add optional `timeoutMs` parameter with `AbortSignal.timeout()` to both fetch calls |
| `src/slack/monitor/media.test.ts` | Update assertions to use `expect.objectContaining()` for new signal property |
## Test Plan
- [x] `pnpm vitest run src/slack/monitor/media.test.ts` - 11 tests pass
- [x] `pnpm lint src/slack/monitor/media.ts` - No warnings/errors
- [ ] Manual: Verify timeout behavior with slow/hanging server (simulated)
## Related
Fixes #6851
---
🤖 Generated with [Claude Code](https://claude.ai/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
Adds explicit request timeouts to Slack media download flow by attaching `AbortSignal.timeout()` to both the initial authenticated request (manual redirect handling) and the follow-up CDN fetch. Tests were updated to assert fetch options via `expect.objectContaining()` to accommodate the new `signal` field.
This change fits into the existing Slack media ingestion pipeline (`resolveSlackMedia` -> `fetchRemoteMedia` -> custom `fetchImpl` -> `fetchWithSlackAuth`) by ensuring outbound Slack CDN fetches don't hang indefinitely under slow/unresponsive conditions.
<h3>Confidence Score: 3/5</h3>
- This PR is likely safe to merge, but runtime compatibility depends on the minimum supported Node version for AbortSignal.timeout().
- The change is small and well-tested at the unit level, but it introduces a dependency on `AbortSignal.timeout()` existing at runtime; if the project supports older Node runtimes, this can cause a hard runtime failure.
- src/slack/monitor/media.ts (runtime compatibility / Node version support)
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#23745: fix(resilience): add timeout to unguarded fetch calls in browser su...
by kevinWangSheng · 2026-02-22
81.8%
#14847: fix(slack): preserve auth across Slack-hosted file redirects
by natashache · 2026-02-12
79.5%
#18763: fix(slack): add auth header when downloading forwarded attachment i...
by amabito · 2026-02-17
76.3%
#16573: fix(signal): increase attachment fetch timeout to 30s (#16545)
by robbyczgw-cla · 2026-02-14
75.6%
#20479: fix(slack): keep replies flowing for oversized file uploads
by olyashok · 2026-02-19
75.6%
#7247: fix(telegram): abort stale getUpdates connections after long-poll t...
by JanderV · 2026-02-02
74.9%
#17879: fix: prevent Slack auth errors from crashing the entire gateway
by zuyan9 · 2026-02-16
74.5%
#22096: fix(slack): traverse .original for Slack SDK errors; pass recipient...
by maiclaw · 2026-02-20
73.5%
#23787: Handle transient Slack request errors without crashing the gateway
by graysurf · 2026-02-22
72.8%
#19540: feat: add timeout and exponential backoff retry for frontend API calls
by Mozzzaic · 2026-02-17
72.6%