Skip to content

Fix: add SSRF guard for agent test_db_connection endpoint#14860

Open
dale053 wants to merge 3 commits into
infiniflow:mainfrom
dale053:fix/ssrf-test-db-connection-14858
Open

Fix: add SSRF guard for agent test_db_connection endpoint#14860
dale053 wants to merge 3 commits into
infiniflow:mainfrom
dale053:fix/ssrf-test-db-connection-14858

Conversation

@dale053
Copy link
Copy Markdown
Contributor

@dale053 dale053 commented May 12, 2026

What problem does this PR solve?

Closes #14858

The test_db_connection endpoint in the agent API accepts a user-supplied host and connects to it directly via database drivers (MySQL/PostgreSQL) without any validation. This allows an attacker to probe internal network addresses (e.g. 127.0.0.1, 10.x.x.x, link-local, etc.) through the server — a classic Server-Side Request Forgery (SSRF) vulnerability.

This PR adds an SSRF guard that resolves the host and rejects any address that is not globally routable before the database connection is attempted.

Changes:

  • common/ssrf_guard.py — Added assert_host_is_safe(), a host-level counterpart of the existing assert_url_is_safe(), designed for non-HTTP protocols (database drivers) where there is no URL to parse.
  • api/apps/restful_apis/agent_api.py — Call assert_host_is_safe(req["host"]) at the top of test_db_connection so that non-public hosts are rejected early with a clear error message.

Fixes #14858

Type of change

  • Bug Fix (non-breaking change which fixes an issue)
  • New Feature (non-breaking change which adds functionality)
  • Documentation Update
  • Refactoring
  • Performance Improvement
  • Other (please describe):

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. 🐞 bug Something isn't working, pull request that fix bug. labels May 12, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 215027f6-69a6-43a9-9c9c-808fa4fb26e2

📥 Commits

Reviewing files that changed from the base of the PR and between d133c8a and d55c2c5.

📒 Files selected for processing (1)
  • api/apps/restful_apis/agent_api.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • api/apps/restful_apis/agent_api.py

📝 Walkthrough

Walkthrough

A new host-level SSRF guard validates hostnames resolve to globally routable IPs and the test_db_connection endpoint now calls it, returning errors on invalid or unresolvable hosts and using the validated safe_host for all DB connection paths.

Changes

SSRF host validation for database connection endpoint

Layer / File(s) Summary
SSRF host validation function
common/ssrf_guard.py
New assert_host_is_safe(host: str) resolves hostnames, normalizes IPv4-mapped IPv6, requires resolved addresses to be is_global, returns the first validated public IP string, and raises ValueError with logged warnings for empty, unresolvable, or non-public hosts.
test_db_connection endpoint protection
api/apps/restful_apis/agent_api.py
Import assert_host_is_safe; wrap validation in try/except to return get_data_error_result on ValueError or OSError DNS failures; use safe_host for MySQL/MariaDB/OceanBase, Postgres, MSSQL (ODBC SERVER), IBM DB2 (HOSTNAME and logs), and Trino DBAPI connection calls.

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped a path through DNS and logs,
Sniffed out maps and versus fogs,
I nip at private IPs tight—
Only public hops may sight. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding an SSRF guard for the agent test_db_connection endpoint.
Description check ✅ Passed The description clearly explains the problem (SSRF vulnerability), solution (new assert_host_is_safe function), changes made, and includes the required type of change checkbox marked correctly.
Linked Issues check ✅ Passed The changes fully address issue #14858 by implementing host validation before database connections across all supported drivers and rejecting non-globally-routable addresses.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the SSRF vulnerability in test_db_connection; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
api/apps/restful_apis/agent_api.py (1)

711-714: ⚡ Quick win

Use get_data_error_result for client validation errors.

server_error_response reports a server-side failure, but a ValueError from assert_host_is_safe is a request-validation failure (4xx-style). Elsewhere in this file, ValueError from validators is consistently surfaced via get_data_error_result (e.g. lines 514-515, 938-939). Recommend aligning with that pattern (already folded into the diff above).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/apps/restful_apis/agent_api.py` around lines 711 - 714, The code treats a
validation failure from assert_host_is_safe as a server error; change the
exception handling to return a client validation response by calling
get_data_error_result with the exception message instead of
server_error_response. Locate the try/except around
assert_host_is_safe(req["host"]) and replace the except block to return
get_data_error_result(str(exc)) so it matches the existing pattern used
elsewhere in this file (see other ValueError handlers like the ones around lines
where get_data_error_result is used).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/apps/restful_apis/agent_api.py`:
- Around line 711-714: The call to assert_host_is_safe currently discards the
validated IP, allowing a TOCTOU DNS-rebind when later passing req["host"] to DB
drivers; change the code to capture the return value (e.g., safe_host =
assert_host_is_safe(req["host"])) and then use safe_host in all subsequent
connection calls instead of req["host"] (apply to
MySQLDatabase/PostgresqlDatabase constructors, pyodbc.connect, ibm_db.connect,
trino.dbapi.connect and the oceanbase/postgres/mssql (SERVER=...)/IBM DB2
(HOSTNAME=...) branches). If hostname preservation is required for TLS/SNI, wrap
the connect call with pin_dns(req["host"], safe_host) instead; ensure you still
call assert_host_is_safe and use its returned IP in the connect logic or the
pin_dns context.

---

Nitpick comments:
In `@api/apps/restful_apis/agent_api.py`:
- Around line 711-714: The code treats a validation failure from
assert_host_is_safe as a server error; change the exception handling to return a
client validation response by calling get_data_error_result with the exception
message instead of server_error_response. Locate the try/except around
assert_host_is_safe(req["host"]) and replace the except block to return
get_data_error_result(str(exc)) so it matches the existing pattern used
elsewhere in this file (see other ValueError handlers like the ones around lines
where get_data_error_result is used).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7916d9f-0173-4b83-abcf-96964219b045

📥 Commits

Reviewing files that changed from the base of the PR and between 5e46457 and e04a2a0.

📒 Files selected for processing (2)
  • api/apps/restful_apis/agent_api.py
  • common/ssrf_guard.py

Comment thread api/apps/restful_apis/agent_api.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/apps/restful_apis/agent_api.py`:
- Around line 711-714: Catch both ValueError and OSError/socket.gaierror from
assert_host_is_safe and treat them as user/data errors by returning
get_data_error_result; additionally add a logging.warning entry when a host is
rejected that records the offending req["host"] and the requesting tenant/user
(pull from req or request context) so rejections are auditable, and if desired
log the full exception at debug level but do not surface resolver details in the
returned get_data_error_result; update the try/except around assert_host_is_safe
to reflect these changes and avoid letting resolver errors bubble up to
server_error_response.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cbca43ff-2ebc-4e14-939e-da0ac9f339fd

📥 Commits

Reviewing files that changed from the base of the PR and between e04a2a0 and d133c8a.

📒 Files selected for processing (1)
  • api/apps/restful_apis/agent_api.py

Comment thread api/apps/restful_apis/agent_api.py
@dale053
Copy link
Copy Markdown
Contributor Author

dale053 commented May 13, 2026

Hi, @wangq8
Could you please review this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 bug Something isn't working, pull request that fix bug. size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: SRF via /agents/test_db_connection — no host/port validation allows internal network scanning

1 participant