[PR #32165] security: use SSRF-protected proxy for remote schema fetching #33589

Open
opened 2026-02-21 20:53:33 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/32165

State: open
Merged: No


Vulnerability identified and fix provided by Kolega.dev

Unrestricted Remote URL Fetching in API Tool Schema Parsing

Location

api/services/tools/api_tools_manage_service.py:187-209

Description

The get_api_tool_provider_remote_schema method allows users to provide arbitrary URLs to fetch API schemas. While the function does call ApiToolManageService.parser_api_schema to validate the schema, there are no restrictions on which URLs can be fetched. An attacker can exploit this to perform SSRF attacks against internal services, port scanning, or fetch sensitive files from the network.

Analysis Notes

This is a genuine SSRF vulnerability. The get_api_tool_provider_remote_schema() method uses httpx.get() directly (imported as 'from httpx import get') to fetch user-provided URLs without SSRF protection. The endpoint is exposed at /workspaces/current/tool-provider/api/remote and accepts arbitrary URLs via the 'url' query parameter. While the endpoint requires authentication (@login_required, @account_initialization_required), authenticated users can still abuse this to: (1) probe internal network services and metadata endpoints (AWS 169.254.169.254, GCP, etc.), (2) port scan internal infrastructure, (3) access internal APIs not exposed externally. The codebase has a dedicated ssrf_proxy module (core/helper/ssrf_proxy.py) that is used elsewhere but not here. The schema validation after fetch (ApiToolManageService.parser_api_schema) does not prevent the SSRF - the malicious request is already made. Fix: Replace httpx.get() with ssrf_proxy.get() to route requests through the SSRF protection proxy, and add URL validation to reject private IP ranges.

Fix Applied

Replaced the direct httpx.get() call with ssrf_proxy.get() from the project's existing SSRF protection module (core/helper/ssrf_proxy.py). This routes all remote schema fetch requests through the project's SSRF proxy, which applies private IP range filtering and proxy-based protections consistent with how all other user-facing URL fetches are handled throughout the codebase.

Tests/Linters Ran

  • ruff check (ruff check services/tools/api_tools_manage_service.py): All checks passed
  • ruff format (ruff format --check services/tools/api_tools_manage_service.py): File already formatted
  • mypy (mypy services/tools/api_tools_manage_service.py --ignore-missing-imports): No errors in changed file (18 pre-existing errors in unrelated files)
  • AST parse verification: Confirmed no syntax errors and correct ssrf_proxy.get usage
  • Unit/integration tests: Could not run due to missing system dependency (mpfr.h for gmpy2) in the build environment - this is a pre-existing environment issue unrelated to this change. The integration tests at tests/test_containers_integration_tests/services/tools/test_api_tools_manage_service.py and unit tests at tests/unit_tests/core/helper/test_ssrf_proxy.py should be verified in CI.
**Original Pull Request:** https://github.com/langgenius/dify/pull/32165 **State:** open **Merged:** No --- *Vulnerability identified and fix provided by [Kolega.dev](https://kolega.dev/)* ## Unrestricted Remote URL Fetching in API Tool Schema Parsing ## Location `api/services/tools/api_tools_manage_service.py:187-209` ## Description The get_api_tool_provider_remote_schema method allows users to provide arbitrary URLs to fetch API schemas. While the function does call ApiToolManageService.parser_api_schema to validate the schema, there are no restrictions on which URLs can be fetched. An attacker can exploit this to perform SSRF attacks against internal services, port scanning, or fetch sensitive files from the network. ## Analysis Notes This is a genuine SSRF vulnerability. The get_api_tool_provider_remote_schema() method uses httpx.get() directly (imported as 'from httpx import get') to fetch user-provided URLs without SSRF protection. The endpoint is exposed at /workspaces/current/tool-provider/api/remote and accepts arbitrary URLs via the 'url' query parameter. While the endpoint requires authentication (@login_required, @account_initialization_required), authenticated users can still abuse this to: (1) probe internal network services and metadata endpoints (AWS 169.254.169.254, GCP, etc.), (2) port scan internal infrastructure, (3) access internal APIs not exposed externally. The codebase has a dedicated ssrf_proxy module (core/helper/ssrf_proxy.py) that is used elsewhere but not here. The schema validation after fetch (ApiToolManageService.parser_api_schema) does not prevent the SSRF - the malicious request is already made. Fix: Replace httpx.get() with ssrf_proxy.get() to route requests through the SSRF protection proxy, and add URL validation to reject private IP ranges. ## Fix Applied Replaced the direct `httpx.get()` call with `ssrf_proxy.get()` from the project's existing SSRF protection module (`core/helper/ssrf_proxy.py`). This routes all remote schema fetch requests through the project's SSRF proxy, which applies private IP range filtering and proxy-based protections consistent with how all other user-facing URL fetches are handled throughout the codebase. ## Tests/Linters Ran - **ruff check** (`ruff check services/tools/api_tools_manage_service.py`): All checks passed - **ruff format** (`ruff format --check services/tools/api_tools_manage_service.py`): File already formatted - **mypy** (`mypy services/tools/api_tools_manage_service.py --ignore-missing-imports`): No errors in changed file (18 pre-existing errors in unrelated files) - **AST parse verification**: Confirmed no syntax errors and correct `ssrf_proxy.get` usage - **Unit/integration tests**: Could not run due to missing system dependency (`mpfr.h` for `gmpy2`) in the build environment - this is a pre-existing environment issue unrelated to this change. The integration tests at `tests/test_containers_integration_tests/services/tools/test_api_tools_manage_service.py` and unit tests at `tests/unit_tests/core/helper/test_ssrf_proxy.py` should be verified in CI.
yindo added the pull-request label 2026-02-21 20:53:33 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#33589