dify - 💡(How to fix) Fix Security: SSRF bypass in ApiBasedToolSchemaParser - unprotected httpx.get() call

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

The ApiBasedToolSchemaParser.api_url_to_tool_bundle() method in api/core/tools/utils/parser.py makes a direct httpx.get() call to user-provided URLs without using the SSRF proxy. This allows attackers to bypass SSRF protections and make requests to internal network resources.

Root Cause

The ApiBasedToolSchemaParser.api_url_to_tool_bundle() method in api/core/tools/utils/parser.py makes a direct httpx.get() call to user-provided URLs without using the SSRF proxy. This allows attackers to bypass SSRF protections and make requests to internal network resources.

Code Example

# Line 379 in api/core/tools/utils/parser.py
response = httpx.get(
    api_url, headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "}, timeout=5
)

---

from core.helper import ssrf_proxy

# Instead of:
# response = httpx.get(api_url, headers={...}, timeout=5)

# Use:
response = ssrf_proxy.get(api_url, headers={...}, timeout=(5, 10))
RAW_BUFFERClick to expand / collapse

Summary

The ApiBasedToolSchemaParser.api_url_to_tool_bundle() method in api/core/tools/utils/parser.py makes a direct httpx.get() call to user-provided URLs without using the SSRF proxy. This allows attackers to bypass SSRF protections and make requests to internal network resources.

Affected File

  • api/core/tools/utils/parser.py (line 379)

Vulnerable Code

# Line 379 in api/core/tools/utils/parser.py
response = httpx.get(
    api_url, headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "}, timeout=5
)

The api_url is provided by users in OpenAPI plugin manifests and is passed directly to httpx.get() without any validation or SSRF protection.

Impact

  • SSRF Attack: Attackers can scan internal network infrastructure
  • Internal Service Access: Access to local services (192.168.x.x, 10.x.x.x, 172.16-31.x.x, localhost)
  • Metadata Access: Potential access to cloud metadata endpoints (169.254.169.254)
  • Proxy Bypass: Completely bypasses the configured SSRF proxy used elsewhere in the codebase

Recommendation

Replace the direct httpx.get() call with ssrf_proxy.get() to ensure all external requests go through the SSRF protection layer:

from core.helper import ssrf_proxy

# Instead of:
# response = httpx.get(api_url, headers={...}, timeout=5)

# Use:
response = ssrf_proxy.get(api_url, headers={...}, timeout=(5, 10))

This ensures consistency with the rest of the codebase and maintains SSRF protection for all external requests.

References

The SSRF proxy implementation is in api/core/helper/ssrf_proxy.py and is used correctly in other parts of the codebase (e.g., api/core/tools/utils/web_reader_tool.py).

Severity

MEDIUM (could be HIGH depending on internal network configuration)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING