Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugins/image_gen/openai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ def _load_image_bytes(ref: str) -> Tuple[bytes, str]:
ref = ref.strip()
lower = ref.lower()
if lower.startswith(("http://", "https://")):
from tools.url_safety import is_safe_url

if not is_safe_url(ref):
raise ValueError(
f"Refusing to fetch image from unsafe URL: {ref}"
)
import requests

resp = requests.get(ref, timeout=60)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 SSRF redirect bypass — is_safe_url pre-flight check defeated by HTTP redirect following (security)

The PR adds an is_safe_url() pre-flight SSRF check in _load_image_bytes() at plugins/image_gen/openai/__init__.py:137, but the subsequent requests.get(ref, timeout=60) at line 143 silently follows HTTP redirects (up to 30 hops by default) without re-validating each redirect target. An attacker-controlled URL that passes the initial pre-flight check can 302-redirect to http://169.254.169.254/ or any other internal address, achieving SSRF despite the new check. The codebase's own tools/url_safety.py:20-23 documents this as a known limitation and states that redirect-based bypass is mitigated via httpx event hooks — a pattern implemented at gateway/platforms/base.py:541-554 (_ssrf_redirect_guard) and used at lines 754 and 874. The new code uses the synchronous requests library which has no equivalent redirect event hook, leaving the redirect-bypass gap open.

💡 Suggestion: Either disable redirect following (allow_redirects=False) and manually handle redirects while re-validating each Location header with is_safe_url, or switch from requests to httpx (synchronous client available) with follow_redirects=True and an event hook that re-validates each redirect target — matching the established pattern at gateway/platforms/base.py:744-754. The simplest correct fix: use httpx.Client with the same redirect-guard pattern already in the codebase.

📋 Prompt for AI Agents

In plugins/image_gen/openai/__init__.py, in the _load_image_bytes function around line 143, replace the requests.get(ref, timeout=60) call with an httpx.Client call that uses follow_redirects=True and a response event hook that calls is_safe_url on every redirect target. Import httpx at the top of the function (or module). The redirect guard should raise ValueError when a redirect target fails is_safe_url. The established pattern is at gateway/platforms/base.py:541-554 (_ssrf_redirect_guard) and its usage at lines 744-754. Alternatively, set allow_redirects=False on the requests call and manually follow/re-validate each redirect target in a loop — this avoids the httpx dependency but requires more code.

Expand Down
Loading