Skip to content

Commit f71eeda

Browse files
whatevertogoclaude
andcommitted
fix: 脱敏代理 URL 以防止凭据泄露
- 添加 _sanitize_proxy_url 函数,在日志和错误消息中隐藏代理密码 - 简化 _is_socks_proxy 函数,使用元组参数 - 修复 Gemini Code Assist 指出的安全问题 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1650533 commit f71eeda

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

astrbot/core/utils/network_utils.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ def log_connection_failure(
7272
)
7373

7474
if effective_proxy:
75+
sanitized_proxy = _sanitize_proxy_url(effective_proxy)
7576
logger.error(
7677
f"[{provider_label}] 网络/代理连接失败 ({error_type})。"
77-
f"代理地址: {effective_proxy},错误: {error}"
78+
f"代理地址: {sanitized_proxy},错误: {error}"
7879
)
7980
else:
8081
logger.error(f"[{provider_label}] 网络连接失败 ({error_type})。错误: {error}")
@@ -89,10 +90,34 @@ def _is_socks_proxy(proxy: str) -> bool:
8990
Returns:
9091
True if the proxy is a SOCKS proxy (socks4://, socks5://, socks5h://)
9192
"""
92-
proxy_lower = proxy.lower()
93-
return proxy_lower.startswith("socks4://") or proxy_lower.startswith(
94-
"socks5://"
95-
) or proxy_lower.startswith("socks5h://")
93+
return proxy.lower().startswith(("socks4://", "socks5://", "socks5h://"))
94+
95+
96+
def _sanitize_proxy_url(proxy: str) -> str:
97+
"""Sanitize proxy URL by masking password for safe logging.
98+
99+
Args:
100+
proxy: The proxy URL string
101+
102+
Returns:
103+
Sanitized proxy URL with password masked (e.g., "http://user:****@host:port")
104+
"""
105+
try:
106+
from urllib.parse import urlparse, urlunparse
107+
108+
parsed = urlparse(proxy)
109+
if parsed.password:
110+
# Replace password with asterisks
111+
netloc = f"{parsed.username}:****@{parsed.hostname}"
112+
if parsed.port:
113+
netloc += f":{parsed.port}"
114+
sanitized = urlunparse(
115+
(parsed.scheme, netloc, parsed.path, "", "", "")
116+
)
117+
return sanitized
118+
except Exception:
119+
pass
120+
return proxy
96121

97122

98123
def create_proxy_client(
@@ -117,7 +142,8 @@ def create_proxy_client(
117142
if not proxy:
118143
return None
119144

120-
logger.info(f"[{provider_label}] 使用代理: {proxy}")
145+
sanitized_proxy = _sanitize_proxy_url(proxy)
146+
logger.info(f"[{provider_label}] 使用代理: {sanitized_proxy}")
121147

122148
# Check for SOCKS proxy and provide helpful error if socksio is not installed
123149
if _is_socks_proxy(proxy):
@@ -129,7 +155,7 @@ def create_proxy_client(
129155
f" pip install 'httpx[socks]'\n"
130156
f"或者:\n"
131157
f" pip install socksio\n"
132-
f"代理地址: {proxy}"
158+
f"代理地址: {sanitized_proxy}"
133159
) from None
134160

135161
return httpx.AsyncClient(proxy=proxy)

0 commit comments

Comments
 (0)