#23596: fix(msteams): add SSRF validation to file consent upload URL
channel: msteams
size: M
Cluster:
MSTeams SSRF Protection Enhancements
## Summary
`uploadToConsentUrl()` in the MS Teams plugin performs a PUT request to the URL provided in the `fileConsent/invoke` response without any validation. While the invoke activity is authenticated via JWT (Bot Framework webhook auth), a malicious user within an authenticated Teams tenant can craft an invoke with an attacker-controlled `uploadUrl`, causing the bot to PUT file data to arbitrary destinations — a server-side request forgery (SSRF).
### Attack scenario
1. Attacker sends a message triggering a large-file upload flow
2. Bot sends a FileConsentCard with a pending upload stored in memory
3. Attacker crafts a `fileConsent/invoke` activity with `action: "accept"` and `uploadInfo.uploadUrl` pointing to an internal service (e.g. `http://169.254.169.254/latest/meta-data/` or an internal API)
4. Bot performs a PUT request to the attacker-chosen URL with the file buffer as the body
### Fix
This PR adds `validateConsentUploadUrl()` which enforces three checks before any fetch occurs:
1. **HTTPS-only** — rejects `http://`, `file://`, and other protocols
2. **Hostname allowlist** — a new `CONSENT_UPLOAD_HOST_ALLOWLIST` restricted to Microsoft/SharePoint domains that Teams legitimately provides as upload destinations (`sharepoint.com`, `graph.microsoft.com`, `onedrive.com`, etc.)
3. **DNS resolution check** — resolves the hostname and rejects private/reserved IPs (RFC 1918, loopback 127.0.0.0/8, link-local 169.254.0.0/16, IPv6 `::1`, `fe80::/10`, `fc00::/7`) to prevent DNS rebinding attacks
The allowlist is intentionally narrower than `DEFAULT_MEDIA_HOST_ALLOWLIST`, which includes overly broad domains like `blob.core.windows.net` and `trafficmanager.net` that any Azure customer can create endpoints under.
### Testing
47 new tests covering:
- IPv4/IPv6 private IP detection (24 cases)
- Protocol enforcement, hostname allowlist matching, suffix-trick rejection
- DNS failure handling
- End-to-end `uploadToConsentUrl()` integration verifying fetch is never called for blocked URLs
All 201 existing msteams tests continue to pass with zero regressions.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds SSRF protection to MS Teams file consent upload flow by validating URLs before fetch with HTTPS enforcement, Microsoft/SharePoint domain allowlist, and DNS resolution checks to block private IPs. The fix addresses a real security vulnerability where authenticated Teams users could trigger bot PUT requests to arbitrary internal endpoints.
**Key changes:**
- New `validateConsentUploadUrl()` enforces protocol, hostname allowlist, and DNS-based IP checks
- `CONSENT_UPLOAD_HOST_ALLOWLIST` restricts uploads to legitimate Microsoft domains
- `isPrivateOrReservedIP()` blocks RFC 1918, loopback, and link-local ranges
- 47 new tests with comprehensive coverage of validation logic
- Integration point in `uploadToConsentUrl()` ensures all uploads are validated
**Critical issues found:**
- IPv6 validation has gaps: IPv4-mapped addresses like `::ffff:10.0.0.1` bypass private IP detection
- IPv4 validation doesn't verify octets are in 0-255 range, allowing malformed IPs through
Both issues could allow SSRF attacks to succeed despite the validation layer.
<h3>Confidence Score: 2/5</h3>
- This PR has critical security gaps in IPv6 and IPv4 validation that could allow SSRF bypass
- Score reflects two confirmed logical errors in the IP validation layer that directly undermine the SSRF protection: (1) IPv4-mapped IPv6 addresses can bypass private IP detection, and (2) invalid IPv4 octets aren't validated. Both issues create attack vectors that defeat the security fix
- Pay close attention to `extensions/msteams/src/file-consent.ts` - the IP validation logic needs fixes before merge
<sub>Last reviewed commit: f260f9a</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#23629: fix(msteams): sanitize error messages sent to users (CWE-209)
by lewiswigmore · 2026-02-22
90.7%
#23598: fix(msteams): add SSRF protection to attachment downloads via redir...
by lewiswigmore · 2026-02-22
86.6%
#21440: fix(msteams): enforce allowlist checks on redirect hops (SSRF) (#11...
by Asm3r96 · 2026-02-19
80.3%
#11812: fix: MSTeams attachment fetch follows redirects before allowlist ch...
by coygeek · 2026-02-08
79.2%
#10902: fix(msteams): fix inline pasted image downloads
by jlian · 2026-02-07
76.2%
#21739: feat(msteams): support resumable upload sessions for files > 4MB
by krishna-warfade · 2026-02-20
76.2%
#8228: fix(link-understanding): block private IPs and internal hostnames i...
by yubrew · 2026-02-03
75.5%
#19525: security: add SSRF validation for external URLs
by Mozzzaic · 2026-02-17
75.4%
#22884: feat(msteams): add resumable upload sessions with retry and range-a...
by chansuke · 2026-02-21
74.3%
#8339: fix(tts): validate ElevenLabs base URL against allowlist
by yubrew · 2026-02-03
73.0%