d71945b7b9
🚨 Severity: HIGH 💡 Vulnerability: User-provided IMAP `host` in `_test_imap_connection` and `pull_inbox` was not validated against private IPs, creating an SSRF risk. 🎯 Impact: Attackers could abuse the endpoints to port-scan or interact with internal/private network services. 🔧 Fix: Integrated `is_private_ip` from `app.utils.network` to block connections resolving to private, loopback, link-local, or reserved IPs. ✅ Verification: Ran `test_imap_tasks.py` and `test_api_imap_accounts.py` successfully. Checked `ruff` output and diffs. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
30 lines
1001 B
Python
30 lines
1001 B
Python
import re
|
|
|
|
with open("app/api/imap_accounts.py", "r") as f:
|
|
content = f.read()
|
|
|
|
# Add import
|
|
import_stmt = "from app.utils.network import is_private_ip\n"
|
|
content = re.sub(
|
|
r"(from app\.utils\.user_scope import get_current_owner_id\n)",
|
|
r"\1" + import_stmt,
|
|
content
|
|
)
|
|
|
|
# Add SSRF check
|
|
ssrf_check = """
|
|
# Security: Prevent SSRF by blocking connections to internal IPs
|
|
if is_private_ip(host):
|
|
logger.warning("SSRF blocked: Attempt to connect to private IP %s", host)
|
|
return {"success": False, "message": "Connection error: Invalid hostname or IP address"}
|
|
"""
|
|
|
|
content = re.sub(
|
|
r"(def _test_imap_connection\(host: str, port: int, username: str, password: str, use_ssl: bool\) -> dict\[str, Any\]:\n \"\"\"Attempt to connect and log in to the IMAP server.\n\n Returns a dict with ``\{\"success\": bool, \"message\": str\}``\.\n \"\"\"\n)",
|
|
r"\1" + ssrf_check,
|
|
content
|
|
)
|
|
|
|
with open("app/api/imap_accounts.py", "w") as f:
|
|
f.write(content)
|