#11086: fix(mattermost): allow private network for inbound media download
channel: mattermost
stale
Cluster:
Mattermost and Zulip Enhancements
## Summary
The Mattermost monitor calls `fetchRemoteMedia()` to download inbound images and file attachments, but does not pass `ssrfPolicy`. This causes the SSRF guard to block downloads when `baseUrl` points to a private/internal IP (e.g. `127.0.0.1`), silently dropping all inbound media.
## Fix
Add `ssrfPolicy: { allowPrivateNetwork: true }` to the `fetchRemoteMedia` call in the Mattermost monitor. This matches the pattern already used in the loader code, which derives `allowPrivateNetwork` from `baseUrl` being set.
## Context
When Mattermost runs on localhost or a private network (common for self-hosted setups), the SSRF guard throws `SsrFBlockedError: Blocked: private/internal IP address`. The error is caught by the media resolution try/catch and swallowed, so images are silently skipped with no user-facing error.
Since `baseUrl` is explicitly configured by the user to point at a specific Mattermost server, the media download should be allowed to reach it.
Fixes #11083
## Testing
- Verified the type-check passes (`tsc --noEmit` reports no errors on `monitor.ts`)
- Traced the full code path from `monitor.ts` → `fetchRemoteMedia` → `fetchWithSsrFGuard` → `resolvePinnedHostnameWithPolicy` to confirm that `allowPrivateNetwork: true` bypasses the private IP check
🤖 AI-assisted (Claude via OpenClaw). Lightly tested — no integration test run (build requires full dev env setup).
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the Mattermost inbound media download path to pass an explicit SSRF policy into `core.channel.media.fetchRemoteMedia()`, allowing downloads from private/internal network addresses. This aligns Mattermost’s monitor behavior with other parts of the codebase that already opt into `allowPrivateNetwork` for user-configured endpoints, preventing inbound attachments from being silently dropped when Mattermost is hosted on localhost/private IPs.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is narrowly scoped to a single call site, uses an existing SSRF guard knob (`allowPrivateNetwork`) already supported by the networking layer, and does not alter broader request/URL handling logic. No additional issues were found in the changed code path.
- No files require special attention
<!-- 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
#10394: feat(mattermost): add image attachment support for inbound messages
by mithril-logic · 2026-02-06
80.1%
#10027: Mattermost: fix attachment downloads (GET + private-network hosts)
by transportrefer · 2026-02-06
78.9%
#19942: feat(telegram): configurable SSRF policy for media fetch
by onewesong · 2026-02-18
78.9%
#8228: fix(link-understanding): block private IPs and internal hostnames i...
by yubrew · 2026-02-03
78.6%
#19525: security: add SSRF validation for external URLs
by Mozzzaic · 2026-02-17
76.6%
#22644: feat(web-fetch): add allowPrivateNetwork config for web_fetch
by qingxuecc · 2026-02-21
76.3%
#14847: fix(slack): preserve auth across Slack-hosted file redirects
by natashache · 2026-02-12
75.0%
#23598: fix(msteams): add SSRF protection to attachment downloads via redir...
by lewiswigmore · 2026-02-22
74.8%
#20913: fix: intercept Discord embed images to enforce mediaMaxMb
by MumuTW · 2026-02-19
74.1%
#16990: fix(media): strip auth headers on cross-origin redirect in download...
by AI-Reviewer-QS · 2026-02-15
73.8%