fix: 优化同步上游模型,过滤克隆载荷中的敏感 credentials 字段,规避重写导致脱敏密钥丢失/清空的事故风险

This commit is contained in:
liumangmang
2026-07-02 17:05:44 +08:00
parent 316ef24188
commit 852bf84246
2 changed files with 17 additions and 4 deletions
+11 -2
View File
@@ -67,6 +67,12 @@ logger = logging.getLogger(__name__)
MASK = "***" MASK = "***"
SECRET_KEYS = {"password", "token", "key", "secret", "api_key"} SECRET_KEYS = {"password", "token", "key", "secret", "api_key"}
SENSITIVE_CREDENTIAL_KEYS = {
"access_token", "refresh_token", "id_token",
"api_key", "session_key", "cookie",
"aws_secret_access_key", "aws_session_token",
"service_account_json", "service_account", "private_key",
}
ALGORITHMS = {"max_plus_percent", "average_plus_percent", "min_plus_percent"} ALGORITHMS = {"max_plus_percent", "average_plus_percent", "min_plus_percent"}
@@ -1391,8 +1397,11 @@ def sync_website_accounts_upstream_models(
continue continue
# 1. 先安全修复 base_url (不依赖同步模型结果) # 1. 先安全修复 base_url (不依赖同步模型结果)
# 在 remote_acc.get("credentials") 基础上进行修改,保留其他非敏感 credentials (例如 compact_model_mapping) # 在 remote_acc.get("credentials") 基础上过滤掉敏感字段,保留其他非敏感 credentials (例如 compact_model_mapping)
current_creds = dict(remote_acc.get("credentials") or {}) current_creds = {
k: v for k, v in (remote_acc.get("credentials") or {}).items()
if k not in SENSITIVE_CREDENTIAL_KEYS
}
current_creds["base_url"] = upstream_base_url current_creds["base_url"] = upstream_base_url
try: try:
+6 -2
View File
@@ -191,14 +191,16 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
# 1001 的两次 update 调用检测 # 1001 的两次 update 调用检测
calls_1001 = [call for call in update_calls if call[0] == "1001"] calls_1001 = [call for call in update_calls if call[0] == "1001"]
assert len(calls_1001) == 2 assert len(calls_1001) == 2
# 第一次安全修复:应当在保留其他非敏感 credentials (如 compact_model_mapping) 的基础上,只将 base_url 变更为 http://upstream-a # 第一次安全修复:应当在保留其他非敏感 credentials (如 compact_model_mapping) 的基础上,只将 base_url 变更为 http://upstream-a,并且过滤掉敏感字段 api_key
assert calls_1001[0][1]["credentials"]["base_url"] == "http://upstream-a" assert calls_1001[0][1]["credentials"]["base_url"] == "http://upstream-a"
assert calls_1001[0][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"} assert calls_1001[0][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"}
assert calls_1001[0][1]["credentials"]["openai_capabilities"] == "caps" assert calls_1001[0][1]["credentials"]["openai_capabilities"] == "caps"
# 第二次同步成功写入:同样保留其他非敏感 credentials,但将 model_mapping 也更新进去 assert "api_key" not in calls_1001[0][1]["credentials"]
# 第二次同步成功写入:同样保留其他非敏感 credentials,过滤掉敏感字段 api_key,将 model_mapping 更新进去
assert calls_1001[1][1]["credentials"]["base_url"] == "http://upstream-a" assert calls_1001[1][1]["credentials"]["base_url"] == "http://upstream-a"
assert calls_1001[1][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"} assert calls_1001[1][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"}
assert calls_1001[1][1]["credentials"]["openai_capabilities"] == "caps" assert calls_1001[1][1]["credentials"]["openai_capabilities"] == "caps"
assert "api_key" not in calls_1001[1][1]["credentials"]
assert calls_1001[1][1]["credentials"]["model_mapping"] == { assert calls_1001[1][1]["credentials"]["model_mapping"] == {
"gpt-3.5-turbo": "gpt-3.5-turbo", "gpt-3.5-turbo": "gpt-3.5-turbo",
"gpt-4": "gpt-4" "gpt-4": "gpt-4"
@@ -222,6 +224,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
calls_1005 = [call for call in update_calls if call[0] == "1005"] calls_1005 = [call for call in update_calls if call[0] == "1005"]
assert len(calls_1005) == 1 assert len(calls_1005) == 1
assert calls_1005[0][1]["credentials"]["base_url"] == "http://upstream-a" assert calls_1005[0][1]["credentials"]["base_url"] == "http://upstream-a"
assert "api_key" not in calls_1005[0][1]["credentials"]
# 1006 失败 (抛错,但应当执行了第一次安全修复的 update_account) # 1006 失败 (抛错,但应当执行了第一次安全修复的 update_account)
item_1006 = next(i for i in items if i.account_id == "1006") item_1006 = next(i for i in items if i.account_id == "1006")
@@ -231,6 +234,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
calls_1006 = [call for call in update_calls if call[0] == "1006"] calls_1006 = [call for call in update_calls if call[0] == "1006"]
assert len(calls_1006) == 1 assert len(calls_1006) == 1
assert calls_1006[0][1]["credentials"]["base_url"] == "http://upstream-a" assert calls_1006[0][1]["credentials"]["base_url"] == "http://upstream-a"
assert "api_key" not in calls_1006[0][1]["credentials"]
# 1007 失败 (上游 base_url 为空,不应当调用 update_account 且不调用同步模型) # 1007 失败 (上游 base_url 为空,不应当调用 update_account 且不调用同步模型)
item_1007 = next(i for i in items if i.account_id == "1007") item_1007 = next(i for i in items if i.account_id == "1007")