fix(aibox): Batch N 波次4+5 LLM 健壮性与权限隔离,Batch N 收束
波次 4 LLM 健壮性(T10/T19/T20/T21/T23 + T14 复现证伪): - T10 调度器 await 改 wait_for 硬超时兜底(task_timeout+30s 宽限), 软取消够不到的卡死路径不再永久停摆调度循环 - T19 FailoverClient 异常收窄为瞬时白名单(Connection/Timeout/ ChunkedEncoding),MissingSchema 等永久配置错误不再污染冷却表 - T20 流式未收到 [DONE] 抛 TransientLLMError,回答无声截断可感知 - T21 env 覆盖黑名单 filter_env_overrides(LD_*/DYLD_*/PATH 等), executors 两处 + process_manager 接入 - T23 压缩后 tool 配对双向修复(失配 tool_calls 剥离防 API 400) - T14 FTS5 复现证伪:JOIN 别名场景表名 MATCH 正常,无需修复 波次 5 权限隔离(T22/T-L17/T-L18;T1/T2 产品决策:仅告警/维持现状): - T22a TOOL_PROFILE_TASK 定时任务精简工具面(无 update_identity/ update_soul/set_proxy) - T22b ProcessManager owner 隔离:bg_write/bg_kill 属主校验, 观察面共享;DeepSeekChat 新增 owner_id 传导 - T1 绑定非回环地址时启动显著告警 - T-L17 model_config env 名按域名推荐(防跨厂商凭据外发) - T-L18 list_profiles 过滤控制字符(防 ANSI 注入) 测试:test_n_fixes.py 增至 62 项;全量 598 passed / 1 failed (Windows 向 ping 用例,环境项),零回归。审计报告补记 §24.7~24.11, README 同步 owner 隔离语义。八轮审计 T 系列 28 项全部处置完毕。
This commit is contained in:
1 parent
7e44025671
commit
67acae708c
10 files changed
+824
-107
No files matched your search
@@ -22,6 +22,36 @@ from typing import Dict, Optional, Tuple
|
||||
|
||||
from common import ConfigManager, constants, Logger
|
||||
|
||||
# T21(审计 2026-08-21):env 覆盖黑名单——工具 schema 中 env 是开放
|
||||
# object,LLM(可被网页内容提示注入诱导)可传 LD_PRELOAD/PYTHONPATH/
|
||||
# PATH 等在 shell=True 之上进一步劫持进程加载(POSIX LD_PRELOAD 可加载
|
||||
# 任意共享库)。命中黑名单的覆盖键拒绝并告警
|
||||
ENV_DENY_EXACT = frozenset({
|
||||
"PATH", "PYTHONPATH", "PYTHONHOME", "SHELL", "IFS",
|
||||
"LD_LIBRARY_PATH", "LD_PRELOAD", "LD_AUDIT",
|
||||
"DYLD_LIBRARY_PATH", "DYLD_INSERT_LIBRARIES",
|
||||
"PSMODULEPATH", "COMSPEC",
|
||||
})
|
||||
ENV_DENY_PREFIXES = ("LD_", "DYLD_")
|
||||
|
||||
|
||||
def filter_env_overrides(env) -> Tuple[Dict, list]:
|
||||
"""T21:过滤 env 覆盖项,返回 (安全覆盖, 被拒绝键列表)。
|
||||
|
||||
键大小写不敏感匹配(Windows 环境变量不区分大小写);
|
||||
LD_*/DYLD_* 前缀整体拒绝(加载器劫持面)。
|
||||
"""
|
||||
if not env:
|
||||
return {}, []
|
||||
safe, rejected = {}, []
|
||||
for key, value in dict(env).items():
|
||||
ku = str(key).upper()
|
||||
if ku in ENV_DENY_EXACT or ku.startswith(ENV_DENY_PREFIXES):
|
||||
rejected.append(key)
|
||||
else:
|
||||
safe[key] = value
|
||||
return safe, rejected
|
||||
|
||||
|
||||
class CommandExecutor(ABC):
|
||||
"""命令执行器抽象基类 - 负责执行系统命令"""
|
||||
@@ -293,10 +323,13 @@ class SubprocessCommandExecutor(CommandExecutor):
|
||||
|
||||
self.logger.info(f"执行命令: {command} (work_dir={work_dir})")
|
||||
|
||||
# 准备环境变量
|
||||
# 准备环境变量(T21:黑名单键拒绝,防加载器/解释器劫持)
|
||||
exec_env = os.environ.copy()
|
||||
if env:
|
||||
exec_env.update(env)
|
||||
safe_env, rejected_keys = filter_env_overrides(env)
|
||||
if rejected_keys:
|
||||
self.logger.warning(f"env 覆盖被黑名单拒绝(T21): {rejected_keys}")
|
||||
exec_env.update(safe_env)
|
||||
|
||||
process = None
|
||||
token = None
|
||||
@@ -384,10 +417,13 @@ class SubprocessCommandExecutor(CommandExecutor):
|
||||
output_queue.put(("line", f"📁 工作目录: {work_dir}\n"))
|
||||
output_queue.put(("line", "-" * 50 + "\n"))
|
||||
|
||||
# 准备环境变量
|
||||
# 准备环境变量(T21:黑名单键拒绝,防加载器/解释器劫持)
|
||||
exec_env = os.environ.copy()
|
||||
if env:
|
||||
exec_env.update(env)
|
||||
safe_env, rejected_keys = filter_env_overrides(env)
|
||||
if rejected_keys:
|
||||
self.logger.warning(f"env 覆盖被黑名单拒绝(T21): {rejected_keys}")
|
||||
exec_env.update(safe_env)
|
||||
|
||||
process = None
|
||||
token = None
|
||||
|
||||
Reference in new issue
Block a user