Skip to content

fix(gateway): implement SSRF protection for Discord image downloads - #5915

Closed
Ruzzgar wants to merge 1 commit into
NousResearch:mainfrom
Ruzzgar:fix/discord-gateway-ssrf
Closed

fix(gateway): implement SSRF protection for Discord image downloads#5915
Ruzzgar wants to merge 1 commit into
NousResearch:mainfrom
Ruzzgar:fix/discord-gateway-ssrf

Conversation

@Ruzzgar

@Ruzzgar Ruzzgar commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes a high-impact SSRF issue in the Discord gateway image send flow.

gateway/run.py can pass model-produced image_url values into adapter.send_image(...), and DiscordAdapter.send_image() was downloading those URLs directly with aiohttp before uploading them as Discord attachments.

That meant a remote chat user could potentially steer the model into emitting an internal URL such as:

  • http://127.0.0.1/...
  • http://169.254.169.254/...
  • other private/internal network targets

and cause the gateway host to fetch it.

Root Cause

DiscordAdapter.send_image() accepted arbitrary image URLs and performed a network fetch without applying the existing SSRF protections already used elsewhere in the codebase.

Fix

Added a pre-download safety check in gateway/platforms/discord.py using tools.url_safety.is_safe_url.

Behavior after this change:

  • safe public image URLs continue through the normal native attachment flow
  • unsafe/internal URLs are blocked before any outbound request is made
  • blocked URLs fall back to the base adapter behavior, which sends the URL as text instead of fetching it

Security Impact

This closes a server-side request forgery path from untrusted remote chat input into the Discord gateway host.

Without this fix, an attacker could potentially use model-steered image output to probe or access:

  • localhost services
  • cloud metadata endpoints
  • private/internal network resources reachable from the gateway machine

Tests

Added a regression test in tests/gateway/test_discord_send.py that verifies:

  • unsafe URLs are rejected before any Discord channel lookup/download path runs
  • the adapter falls back to plain text send behavior instead

Files Changed

  • gateway/platforms/discord.py
  • tests/gateway/test_discord_send.py

teknium1 added a commit that referenced this pull request Apr 7, 2026
… tar traversal, credential leakage

Salvaged from PRs #5800 (memosr), #5806 (memosr), #5915 (Ruzzgar), #5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
teknium1 added a commit that referenced this pull request Apr 8, 2026
… tar traversal, credential leakage (#5944)

Salvaged from PRs #5800 (memosr), #5806 (memosr), #5915 (Ruzzgar), #5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
@teknium1

teknium1 commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Merged via #5944 as part of a consolidated security hardening PR. Your Discord SSRF fix was the basis — we extended it to all 9 vulnerable platform adapters (Slack, Telegram, Matrix, Mattermost, Feishu, WeCom, plus the shared cache helpers that protect Signal and WhatsApp). Thanks @Ruzzgar for catching this!

@teknium1 teknium1 closed this Apr 8, 2026
saxster pushed a commit to saxster/hermes-agent that referenced this pull request Apr 8, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
Tommyeds pushed a commit to Tommyeds/hermes-agent that referenced this pull request Apr 12, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 28, 2026
… tar traversal, credential leakage

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
… tar traversal, credential leakage (NousResearch#5944)

Salvaged from PRs NousResearch#5800 (memosr), NousResearch#5806 (memosr), NousResearch#5915 (Ruzzgar), NousResearch#5928 (Awsh1).

Changes:
- Use hmac.compare_digest for API key comparison (timing attack prevention)
- Apply provider env var blocklist to Docker containers (credential leakage)
- Replace tar.extractall() with safe extraction in TerminalBench2 (CVE-2007-4559)
- Add SSRF protection via is_safe_url to ALL platform adapters:
  base.py (cache_image_from_url, cache_audio_from_url),
  discord, slack, telegram, matrix, mattermost, feishu, wecom
  (Signal and WhatsApp protected via base.py helpers)
- Update tests: mock is_safe_url in Mattermost download tests
- Add security tests for tar extraction (traversal, symlinks, safe files)
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