现象
作业输出采用 JSON 或 Python 字典文本格式时,password 等已列入脱敏名单的字段仍以明文进入作业执行结果。例如同一个字段 password=value 会被屏蔽,而 {"password": "value"} 不会。
触发场景
正常已授权作业在目标主机输出包含敏感字段的 JSON/字典文本,Ansible Executor 产生带 stdout/stderr/error_message 的真实主机结果,携带有效回调身份调用 ansible_task_callback;每次包含引号键名的此类输出都触发,不需要伪造用户或绕过回调鉴权。短输出小于回调截断阈值即可。
业务影响
原本应由公共脱敏函数屏蔽的密码/私钥字段值被保留在 JobExecution.execution_results,扩大到作业结果持久化及其授权读取范围。只认定敏感输出未脱敏与持久化,不声称跨租户读取或已发生真实凭据泄露。
根因(设计层)
server/apps/rpc/sensitive.py:23-29 的 _SENSITIVE_ASSIGNMENT_RE 要求 key 后直接出现空白及 : 或 =;JSON/Python repr 的 key 后有闭合引号,因此匹配失败。_sanitize_string(45-49)没有解析或处理引号键,sanitize_sensitive_data 对字符串(68-69)只能走该分支。
涉及文件
根因:server/apps/rpc/sensitive.py:23-29、45-49、52-70。生产/消费证据:agents/ansible-executor/service/ansible_runner.py:482-504;agents/ansible-executor/service/callback_delivery_service.py:42-45、108-120;server/apps/job_mgmt/nats_api.py:191-193;server/apps/job_mgmt/services/ansible_callback_service.py:90-103、122-150、153-182、187-214。基线 9396b6d。
调用链
Ansible _build_parsed_host_result 保留命令输出 → _build_task_result 将 parsed_results 放入 result → CallbackDeliveryMixin 通过 NATS 发送 result → ansible_task_callback → handle_ansible_task_callback(有效回调身份、锁内处理)→ _write_terminal → _normalize_results → _host_execution_result → sanitize_sensitive_data → _sanitize_string → execution.execution_results/save。
证据 / 复现
固定基线源码隔离探针使用纯合成标记:真实 dict 与 password=value 对照正常;JSON 引号键和 Python repr 引号键均保留标记;抽取当前 _host_execution_result 原始函数执行后 stdout/stderr/error_message 三字段均保留标记。已有 test_sensitive_pure.py:82-99 只覆盖无引号键;job_mgmt/tests/test_rpc_sensitive_contract_service.py:18-63 明确要求回调输出脱敏,但没有该文本形态。已核验:回调身份/事务/幂等保护正确存在,但只保护状态更新;上游输出大小限制和凭据载荷清理没有脱敏短输出中的引号键。探针不等价真实 NATS/数据库端到端测试。
建议修复方向
在公共字符串脱敏逻辑补齐双引号 JSON 键和单引号 Python repr 键,同时覆盖带转义引号的值及嵌入日志中的对象文本;继续递归处理 dict/list,保持非敏感文本和现有赋值格式行为。优先补充纯函数失败用例,并在回调服务契约测试中断言 JSON 输出持久化后不含合成标记。
功能影响 / 回归风险
保持 RPC subject、参数、响应字段、默认值、回调身份与组织权限不变;变化只限已列入敏感名单的字段文本改为既有 *** 占位,作业消费者仍收到字符串。不得粗暴删除所有 JSON 或改变执行结果结构。无需数据库结构迁移;历史结果不会自动修复,若要清理需按结果保留策略单独处理。回滚可回退脱敏补丁,不涉及不可逆数据迁移;回归覆盖普通文本、引号/转义、空值、嵌套结构、现有 PEM 和赋值格式。
严重性判断
Medium:正常作业回调可达且格式命中时必然绕过既有脱敏并持久化,但前提是作业自身输出敏感字段;未证明未授权用户能读取、也未读取任何真实凭据。
严重度:Medium 工作量:S
负责人:@zhouzhuangjie
现象
作业输出采用 JSON 或 Python 字典文本格式时,password 等已列入脱敏名单的字段仍以明文进入作业执行结果。例如同一个字段 password=value 会被屏蔽,而 {"password": "value"} 不会。
触发场景
正常已授权作业在目标主机输出包含敏感字段的 JSON/字典文本,Ansible Executor 产生带 stdout/stderr/error_message 的真实主机结果,携带有效回调身份调用 ansible_task_callback;每次包含引号键名的此类输出都触发,不需要伪造用户或绕过回调鉴权。短输出小于回调截断阈值即可。
业务影响
原本应由公共脱敏函数屏蔽的密码/私钥字段值被保留在 JobExecution.execution_results,扩大到作业结果持久化及其授权读取范围。只认定敏感输出未脱敏与持久化,不声称跨租户读取或已发生真实凭据泄露。
根因(设计层)
server/apps/rpc/sensitive.py:23-29 的 _SENSITIVE_ASSIGNMENT_RE 要求 key 后直接出现空白及 : 或 =;JSON/Python repr 的 key 后有闭合引号,因此匹配失败。_sanitize_string(45-49)没有解析或处理引号键,sanitize_sensitive_data 对字符串(68-69)只能走该分支。
涉及文件
根因:server/apps/rpc/sensitive.py:23-29、45-49、52-70。生产/消费证据:agents/ansible-executor/service/ansible_runner.py:482-504;agents/ansible-executor/service/callback_delivery_service.py:42-45、108-120;server/apps/job_mgmt/nats_api.py:191-193;server/apps/job_mgmt/services/ansible_callback_service.py:90-103、122-150、153-182、187-214。基线 9396b6d。
调用链
Ansible _build_parsed_host_result 保留命令输出 → _build_task_result 将 parsed_results 放入 result → CallbackDeliveryMixin 通过 NATS 发送 result → ansible_task_callback → handle_ansible_task_callback(有效回调身份、锁内处理)→ _write_terminal → _normalize_results → _host_execution_result → sanitize_sensitive_data → _sanitize_string → execution.execution_results/save。
证据 / 复现
固定基线源码隔离探针使用纯合成标记:真实 dict 与 password=value 对照正常;JSON 引号键和 Python repr 引号键均保留标记;抽取当前 _host_execution_result 原始函数执行后 stdout/stderr/error_message 三字段均保留标记。已有 test_sensitive_pure.py:82-99 只覆盖无引号键;job_mgmt/tests/test_rpc_sensitive_contract_service.py:18-63 明确要求回调输出脱敏,但没有该文本形态。已核验:回调身份/事务/幂等保护正确存在,但只保护状态更新;上游输出大小限制和凭据载荷清理没有脱敏短输出中的引号键。探针不等价真实 NATS/数据库端到端测试。
建议修复方向
在公共字符串脱敏逻辑补齐双引号 JSON 键和单引号 Python repr 键,同时覆盖带转义引号的值及嵌入日志中的对象文本;继续递归处理 dict/list,保持非敏感文本和现有赋值格式行为。优先补充纯函数失败用例,并在回调服务契约测试中断言 JSON 输出持久化后不含合成标记。
功能影响 / 回归风险
保持 RPC subject、参数、响应字段、默认值、回调身份与组织权限不变;变化只限已列入敏感名单的字段文本改为既有 *** 占位,作业消费者仍收到字符串。不得粗暴删除所有 JSON 或改变执行结果结构。无需数据库结构迁移;历史结果不会自动修复,若要清理需按结果保留策略单独处理。回滚可回退脱敏补丁,不涉及不可逆数据迁移;回归覆盖普通文本、引号/转义、空值、嵌套结构、现有 PEM 和赋值格式。
严重性判断
Medium:正常作业回调可达且格式命中时必然绕过既有脱敏并持久化,但前提是作业自身输出敏感字段;未证明未授权用户能读取、也未读取任何真实凭据。
严重度:Medium 工作量:S
负责人:@zhouzhuangjie